mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
rm
This commit is contained in:
parent
2aee9c7bf3
commit
7b7238bb90
@ -1,262 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
#include "lv_conf.h"
|
|
||||||
|
|
||||||
//GT911配置参数表
|
|
||||||
//配置文件的版本号(新下发的配置版本号大于原版本,或等于原版本号但配置内容有变化时保存,
|
|
||||||
//版本号版本正常范围:'A'~'Z',发送 0x00 则将版本号初始化为'A')
|
|
||||||
const uint8_t GT911_CfgTab[] = {
|
|
||||||
0x41,0x20,0x03,0xe0,0x01,0x0A,0x0D,0x00,0x01,0x08,0x28,0x05,0x50,0x32,0x03,0x05,
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x2A,0x0B,0x17,0x15,
|
|
||||||
0x31,0x0D,0x00,0x00,0x03,0xBA,0x04,0x2D,0x00,0x00,0x00,0x00,0x00,0x03,0x64,0x32,
|
|
||||||
0x00,0x00,0x00,0x0F,0x94,0x94,0xC5,0x02,0x07,0x00,0x00,0x04,0x8D,0x13,0x00,0x5C,
|
|
||||||
0x1E,0x00,0x3C,0x30,0x00,0x29,0x4C,0x00,0x1F,0x78,0x00,0x1F,0x00,0x00,0x00,0x00,
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
||||||
0x16,0x14,0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0xFF,0xFF,0xFF,0x00,0x00,
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
|
|
||||||
0x04,0x06,0x08,0x0A,0x0F,0x10,0x12,0x16,0x18,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
|
|
||||||
0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x01};
|
|
||||||
|
|
||||||
#define DEV_ADDR 0x5D
|
|
||||||
|
|
||||||
#define REG_CTRL 0X8040 //GT911控制寄存器
|
|
||||||
#define REG_CFGS 0X8047 //GT911配置寄存器
|
|
||||||
#define REG_CHECK 0X80FF //GT911校验和寄存器
|
|
||||||
#define REG_PID 0X8140 //GT911产品ID寄存器
|
|
||||||
|
|
||||||
#define REG_GSTID 0X814E //当前检测到的触摸情况
|
|
||||||
#define REG_TP1 0X8150 //第一个触摸点数据地址
|
|
||||||
#define REG_TP2 0X8158 //第二个触摸点数据地址
|
|
||||||
#define REG_TP3 0X8160 //第三个触摸点数据地址
|
|
||||||
#define REG_TP4 0X8168 //第四个触摸点数据地址
|
|
||||||
#define REG_TP5 0X8170 //第五个触摸点数据地址
|
|
||||||
|
|
||||||
#define REG_GSTID_READY_Pos 7 // COUNT域是否有效
|
|
||||||
#define REG_GSTID_READY_Msk (0x01 << REG_GSTID_READY_Pos)
|
|
||||||
#define REG_GSTID_COUNT_Pos 0 // 触摸个数,0~5
|
|
||||||
#define REG_GSTID_COUNT_Msk (0x0F << REG_GSTID_COUNT_Pos)
|
|
||||||
|
|
||||||
void delay(void)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < 150; i++)
|
|
||||||
__NOP();
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************************************************************************
|
|
||||||
* 函数名称: GT911_WrReg()
|
|
||||||
* 功能说明: 写GT911寄存器
|
|
||||||
* 输 入: uint16_t reg 要写的寄存器
|
|
||||||
* uint8_t *buf 要写入寄存器的数据
|
|
||||||
* uint8_t len 要写的数据个数
|
|
||||||
* 输 出: uint8_t 1 写入成功 0 写入失败
|
|
||||||
* 注意事项: 无
|
|
||||||
******************************************************************************************************************************************/
|
|
||||||
static uint8_t GT911_WrReg(uint16_t reg, uint8_t *buf, uint8_t len)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
uint8_t ack;
|
|
||||||
|
|
||||||
ack = I2C_Start(I2C0, (DEV_ADDR << 1) | 0);
|
|
||||||
if (ack == 0)
|
|
||||||
goto wr_fail;
|
|
||||||
|
|
||||||
ack = I2C_Write(I2C0, reg >> 8);
|
|
||||||
if (ack == 0)
|
|
||||||
goto wr_fail;
|
|
||||||
|
|
||||||
ack = I2C_Write(I2C0, reg & 0XFF);
|
|
||||||
if (ack == 0)
|
|
||||||
goto wr_fail;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
ack = I2C_Write(I2C0, buf[i]);
|
|
||||||
if (ack == 0)
|
|
||||||
goto wr_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
I2C_Stop(I2C0);
|
|
||||||
delay();
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
wr_fail:
|
|
||||||
I2C_Stop(I2C0);
|
|
||||||
delay();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************************************************************************
|
|
||||||
* 函数名称: GT911_RdReg()
|
|
||||||
* 功能说明: 读GT911寄存器
|
|
||||||
* 输 入: uint16_t reg 要读的寄存器
|
|
||||||
* uint8_t *buf 读出的寄存器值写入数组
|
|
||||||
* uint8_t len 要读的数据个数
|
|
||||||
* 输 出: uint8_t 1 读取成功 0 读取失败
|
|
||||||
* 注意事项: 无
|
|
||||||
******************************************************************************************************************************************/
|
|
||||||
static uint8_t GT911_RdReg(uint16_t reg, uint8_t *buf, uint8_t len)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
uint8_t ack;
|
|
||||||
|
|
||||||
ack = I2C_Start(I2C0, (DEV_ADDR << 1) | 0);
|
|
||||||
if (ack == 0)
|
|
||||||
goto rd_fail;
|
|
||||||
|
|
||||||
ack = I2C_Write(I2C0, reg >> 8);
|
|
||||||
if (ack == 0)
|
|
||||||
goto rd_fail;
|
|
||||||
|
|
||||||
ack = I2C_Write(I2C0, reg & 0XFF);
|
|
||||||
if (ack == 0)
|
|
||||||
goto rd_fail;
|
|
||||||
|
|
||||||
ack = I2C_Start(I2C0, (DEV_ADDR << 1) | 1); //ReStart
|
|
||||||
if (ack == 0)
|
|
||||||
goto rd_fail;
|
|
||||||
|
|
||||||
for (i = 0; i < len - 1; i++)
|
|
||||||
{
|
|
||||||
buf[i] = I2C_Read(I2C0, 1);
|
|
||||||
}
|
|
||||||
buf[i] = I2C_Read(I2C0, 0);
|
|
||||||
|
|
||||||
I2C_Stop(I2C0);
|
|
||||||
delay();
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
rd_fail:
|
|
||||||
I2C_Stop(I2C0);
|
|
||||||
delay();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_m_tp_dev tp_dev;
|
|
||||||
const uint16_t GT911_TPX_TBL[5] = {REG_TP1, REG_TP2, REG_TP3, REG_TP4, REG_TP5};
|
|
||||||
/******************************************************************************************************************************************
|
|
||||||
* 函数名称: GT911_Scan()
|
|
||||||
* 功能说明: 扫描触摸屏识别触摸(采用查询方式)
|
|
||||||
* 输 入: uint16_t *x 读取到的触摸点横坐标
|
|
||||||
* uint16_t *y 读取到的触摸点纵坐标
|
|
||||||
* uint8_t count x和y最多能存储几个触摸点的坐标数据
|
|
||||||
* 输 出: uint8_t 实际扫描到的触摸点个数
|
|
||||||
* 注意事项: 无
|
|
||||||
******************************************************************************************************************************************/
|
|
||||||
void GT911_Scan(void)
|
|
||||||
{
|
|
||||||
uint8_t buf[4], touch_status = 0;
|
|
||||||
uint8_t temp;
|
|
||||||
uint8_t tempsta;
|
|
||||||
|
|
||||||
GT911_RdReg(REG_GSTID, &touch_status, 1);
|
|
||||||
if (touch_status & 0x80 && ((touch_status & 0x0F) < 6))
|
|
||||||
{
|
|
||||||
temp = 0;
|
|
||||||
GT911_WrReg(REG_GSTID, &temp, 1); // 清除READY标志
|
|
||||||
}
|
|
||||||
if ((touch_status & 0x0F) && ((touch_status & 0x0F) < 6))
|
|
||||||
{
|
|
||||||
temp = 0xFF << (touch_status & 0x0F); //将点的个数转换为1的位数,匹配tp_dev.sta定义
|
|
||||||
tempsta = tp_dev.sta; //保存当前的tp_dev.sta值
|
|
||||||
tp_dev.sta = (~temp) | TP_PRES_DOWN;
|
|
||||||
tp_dev.x[4] = tp_dev.x[0]; //保存触点0的数据
|
|
||||||
tp_dev.y[4] = tp_dev.y[0];
|
|
||||||
for (uint32_t i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
if (tp_dev.sta & (1 << i)) //触摸有效?
|
|
||||||
{
|
|
||||||
// for (uint32_t i = 0; i < 150; i++)
|
|
||||||
// __NOP();
|
|
||||||
GT911_RdReg(GT911_TPX_TBL[i], buf, 4); //读取XY坐标值
|
|
||||||
tp_dev.x[i] = (((uint16_t)buf[3] << 8) + buf[2]);
|
|
||||||
tp_dev.y[i] = (((uint16_t)buf[1] << 8) + buf[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tp_dev.x[0] > LV_HOR_RES_MAX || tp_dev.y[0] > LV_VER_RES_MAX) //非法数据(坐标超出了)
|
|
||||||
{
|
|
||||||
if ((touch_status & 0x0F) > 1) //有其他点有数据,则复第二个触点的数据到第一个触点.
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = tp_dev.x[1];
|
|
||||||
tp_dev.y[0] = tp_dev.y[1];
|
|
||||||
}
|
|
||||||
else //非法数据,则忽略此次数据(还原原来的)
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = tp_dev.x[4];
|
|
||||||
tp_dev.y[0] = tp_dev.y[4];
|
|
||||||
touch_status = 0x80;
|
|
||||||
tp_dev.sta = tempsta; //恢复tp_dev.sta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((touch_status & 0x8F) == 0x80) //无触摸点按下
|
|
||||||
{
|
|
||||||
if (tp_dev.sta & TP_PRES_DOWN) //之前是被按下的
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = 0xffff;
|
|
||||||
tp_dev.y[0] = 0xffff;
|
|
||||||
tp_dev.sta &= ~(1 << 7); //标记按键松开
|
|
||||||
}
|
|
||||||
else //之前就没有被按下
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = 0xffff;
|
|
||||||
tp_dev.y[0] = 0xffff;
|
|
||||||
tp_dev.sta &= 0XE0; //清除点有效标记
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************************************************************************
|
|
||||||
* 函数名称: GT911_Init()
|
|
||||||
* 功能说明: GT911初始化
|
|
||||||
* 输 入: 无
|
|
||||||
* 输 出: uint8_t 1 初始化成功 0 初始化失败
|
|
||||||
* 注意事项: 无
|
|
||||||
******************************************************************************************************************************************/
|
|
||||||
uint8_t GT911_Init(void)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint8_t temp[186] = {0};
|
|
||||||
I2C_InitStructure I2C_initStruct;
|
|
||||||
|
|
||||||
PORT_Init(PORTA, PIN10, FUNMUX0_I2C0_SCL, 1); //GPIOA.10配置为I2C0 SCL引脚
|
|
||||||
PORT->PORTA_PULLU |= (1 << PIN10); //必须使能上拉,用于模拟开漏
|
|
||||||
PORT_Init(PORTA, PIN9, FUNMUX1_I2C0_SDA, 1); //GPIOA.9配置为I2C0 SDA引脚
|
|
||||||
PORT->PORTA_PULLU |= (1 << PIN9); //必须使能上拉,用于模拟开漏
|
|
||||||
|
|
||||||
I2C_initStruct.Master = 1;
|
|
||||||
I2C_initStruct.Addr7b = 1;
|
|
||||||
I2C_initStruct.MstClk = 400000;
|
|
||||||
I2C_initStruct.MstIEn = 0;
|
|
||||||
I2C_Init(I2C0, &I2C_initStruct);
|
|
||||||
I2C_Open(I2C0);
|
|
||||||
|
|
||||||
GPIO_Init(GPIOB, PIN7, 0, 0, 1); // 输入,开启下拉。复位时INT为低,选择0xBA作为地址
|
|
||||||
|
|
||||||
// GPIO_Init(GPIOM, PIN20, 1, 0, 0); // GT911复位
|
|
||||||
GPIO_ClrBit(GPIOM, PIN20); // 复位
|
|
||||||
swm_delay(1);
|
|
||||||
GPIO_SetBit(GPIOM, PIN20); // 释放复位
|
|
||||||
swm_delay(1);
|
|
||||||
|
|
||||||
GT911_RdReg(REG_PID, temp, 4);
|
|
||||||
if (strcmp((char *)temp, "911") == 0) // ID==911
|
|
||||||
{
|
|
||||||
temp[0] = 0X02;
|
|
||||||
GT911_WrReg(REG_CTRL, temp, 1); // 软复位
|
|
||||||
swm_delay(10);
|
|
||||||
|
|
||||||
// //更新触摸芯片配置
|
|
||||||
// {
|
|
||||||
// GT911_WrReg(REG_CFGS, (uint8_t *)GT911_CfgTab, sizeof(GT911_CfgTab)); //发送寄存器配置
|
|
||||||
// GT911_RdReg(REG_CFGS, temp, sizeof(GT911_CfgTab));
|
|
||||||
// }
|
|
||||||
|
|
||||||
temp[0] = 0X00;
|
|
||||||
GT911_WrReg(REG_CTRL, temp, 1); // 释放软复位
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef __GT911_H__
|
|
||||||
#define __GT911_H__
|
|
||||||
|
|
||||||
#include "SWM320.h"
|
|
||||||
#include "dev_systick.h"
|
|
||||||
|
|
||||||
#define TP_PRES_DOWN 0x80 //触屏被按下
|
|
||||||
#define CT_MAX_TOUCH 5 //电容屏支持的点数,固定为5点
|
|
||||||
|
|
||||||
//触摸屏控制器
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t x[CT_MAX_TOUCH]; //当前坐标
|
|
||||||
uint16_t y[CT_MAX_TOUCH]; //电容屏有最多5组坐标
|
|
||||||
uint8_t sta; //笔的状态
|
|
||||||
//b7:按下1/松开0;
|
|
||||||
//b6~b5:保留
|
|
||||||
//b4~b0:电容触摸屏按下的点数(0,表示未按下,1表示按下)
|
|
||||||
} _m_tp_dev;
|
|
||||||
|
|
||||||
extern _m_tp_dev tp_dev;
|
|
||||||
|
|
||||||
uint8_t GT911_Init(void);
|
|
||||||
void GT911_Scan(void);
|
|
||||||
|
|
||||||
#endif //__GT911_H__
|
|
@ -1,287 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
#include "lv_conf.h"
|
|
||||||
|
|
||||||
//GT9147配置参数表
|
|
||||||
//第一个字节为版本号(0X60),必须保证新的版本号大于等于GT9147内部
|
|
||||||
//flash原有版本号,才会更新配置.
|
|
||||||
static const uint8_t GT9147_CFG_TBL[] = {
|
|
||||||
0x61, 0xE0, 0x01, 0x10, 0x01, 0x05, 0x0C, 0x00, 0x01, 0x08,
|
|
||||||
0x28, 0x05, 0x50, 0x32, 0x03, 0x05, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x28, 0x0A,
|
|
||||||
0x17, 0x15, 0x31, 0x0D, 0x00, 0x00, 0x02, 0x9B, 0x03, 0x25,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
|
|
||||||
0x00, 0x0F, 0x94, 0x94, 0xC5, 0x02, 0x07, 0x00, 0x00, 0x04,
|
|
||||||
0x8D, 0x13, 0x00, 0x5C, 0x1E, 0x00, 0x3C, 0x30, 0x00, 0x29,
|
|
||||||
0x4C, 0x00, 0x1E, 0x78, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16,
|
|
||||||
0x18, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0x00, 0x02, 0x04, 0x05, 0x06, 0x08, 0x0A, 0x0C,
|
|
||||||
0x0E, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24, 0x28, 0x29, 0xFF,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF};
|
|
||||||
|
|
||||||
void i2c_init(void)
|
|
||||||
{
|
|
||||||
I2C_InitStructure I2C_initStruct;
|
|
||||||
|
|
||||||
PORT_Init(PORTA, PIN8, FUNMUX0_I2C0_SCL, 1);
|
|
||||||
PORT->PORTA_PULLU |= (1 << PIN8);
|
|
||||||
PORT_Init(PORTA, PIN5, FUNMUX1_I2C0_SDA, 1);
|
|
||||||
PORT->PORTA_PULLU |= (1 << PIN5);
|
|
||||||
|
|
||||||
I2C_initStruct.Master = 1;
|
|
||||||
I2C_initStruct.Addr7b = 1;
|
|
||||||
I2C_initStruct.MstClk = 400000;
|
|
||||||
I2C_initStruct.MstIEn = 0;
|
|
||||||
I2C_Init(I2C0, &I2C_initStruct);
|
|
||||||
|
|
||||||
I2C_Open(I2C0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t gt9147_write_reg(uint16_t reg, uint8_t *data, uint8_t len)
|
|
||||||
{
|
|
||||||
I2C0->MSTDAT = GT_CMD_WR; // 发送器件地址+写命令
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_STA_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_WR_Pos); // 发送起始位和从机地址
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
; // 等待发送完成
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 判断是否接收到应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
I2C0->MSTDAT = reg >> 8; // 写入数据
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_WR_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 读应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
I2C0->MSTDAT = reg & 0xFF; // 写入数据
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_WR_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 读应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
I2C0->MSTDAT = *data++; // 写入数据
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_WR_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 读应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_STO_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t gt9147_read_reg(uint16_t reg, uint8_t *data, uint8_t len)
|
|
||||||
{
|
|
||||||
I2C0->MSTDAT = GT_CMD_WR; // 发送器件地址+写命令
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_STA_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_WR_Pos); // 发送起始位和从机地址
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
; // 等待发送完成
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 判断是否接收到应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
I2C0->MSTDAT = reg >> 8; // 写入数据
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_WR_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 读应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
I2C0->MSTDAT = reg & 0xFF; // 写入数据
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_WR_Pos);
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk) // 读应答位
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_STA_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_WR_Pos); // 发送Restart
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
|
|
||||||
I2C0->MSTDAT = GT_CMD_RD; // 发送器件地址+读命令
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_STA_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_WR_Pos); // 发送Restart
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
;
|
|
||||||
if (I2C0->MSTCMD & I2C_MSTCMD_RXACK_Msk)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// 注意,这里只需循环(len - 1)次,因为最后一个字节不需要应答
|
|
||||||
for (uint32_t i = 0; i < len - 1; i++)
|
|
||||||
{
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_RD_Pos) |
|
|
||||||
(0 << I2C_MSTCMD_ACK_Pos); // 产生ACK信号
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
; // 等待接收完成
|
|
||||||
*data++ = I2C0->MSTDAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
I2C0->MSTCMD = (1 << I2C_MSTCMD_RD_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_ACK_Pos) |
|
|
||||||
(1 << I2C_MSTCMD_STO_Pos); // 发送NACK响应,完成后发送STOP
|
|
||||||
while (I2C0->MSTCMD & I2C_MSTCMD_TIP_Msk)
|
|
||||||
; // 等待接收完成
|
|
||||||
*data++ = I2C0->MSTDAT; // 最后一个字节,先发送命令,再读取即可
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//发送GT9147配置参数
|
|
||||||
//mode:0,参数不保存到flash
|
|
||||||
// 1,参数保存到flash
|
|
||||||
void gt9147_send_cfg(uint8_t mode)
|
|
||||||
{
|
|
||||||
uint8_t buf[2];
|
|
||||||
buf[0] = 0;
|
|
||||||
buf[1] = mode; //是否写入到GT9147 FLASH? 即是否掉电保存
|
|
||||||
for (uint32_t i = 0; i < sizeof(GT9147_CFG_TBL); i++)
|
|
||||||
buf[0] += GT9147_CFG_TBL[i]; //计算校验和
|
|
||||||
buf[0] = (~buf[0]) + 1;
|
|
||||||
gt9147_write_reg(GT_CFGS_REG, (uint8_t *)GT9147_CFG_TBL, sizeof(GT9147_CFG_TBL)); //发送寄存器配置
|
|
||||||
swm_delay(5);
|
|
||||||
gt9147_write_reg(GT_CHECK_REG, buf, 2); //写入校验和,和配置更新标记
|
|
||||||
}
|
|
||||||
_m_tp_dev tp_dev;
|
|
||||||
void gt9147_init(void)
|
|
||||||
{
|
|
||||||
// 第一阶段设置端口,并拉低两个端口
|
|
||||||
GPIO_Init(GPIO_GT_RST, PIN_GT_RST, 1, 0, 0); // 复位脚 输出
|
|
||||||
GPIO_ClrBit(GPIO_GT_RST, PIN_GT_RST);
|
|
||||||
GPIO_Init(GPIO_GT_INT, PIN_GT_INT, 1, 0, 0); // 中断脚 输出
|
|
||||||
GPIO_ClrBit(GPIO_GT_INT, PIN_GT_INT);
|
|
||||||
i2c_init();
|
|
||||||
swm_delay(10);
|
|
||||||
// 第二阶段复位芯片
|
|
||||||
GPIO_SetBit(GPIO_GT_RST, PIN_GT_RST); // 拉高开始复位芯片
|
|
||||||
swm_delay(10);
|
|
||||||
// 第三阶段设置中断引脚为 中断功能
|
|
||||||
GPIO_Init(GPIO_GT_INT, PIN_GT_INT, 0, 0, 0);
|
|
||||||
|
|
||||||
swm_delay(100);
|
|
||||||
uint8_t temp[200];
|
|
||||||
// gt9147_read_reg(GT_PID_REG, temp, 4); //读取产品ID
|
|
||||||
// temp[4] = 0;
|
|
||||||
// printf("Product ID:%s\r\n", temp);
|
|
||||||
|
|
||||||
temp[0] = 0x02;
|
|
||||||
gt9147_write_reg(GT_CTRL_REG, temp, 1); //软复位GT9147
|
|
||||||
swm_delay(10);
|
|
||||||
gt9147_read_reg(GT_CFGS_REG, temp, 1);
|
|
||||||
// printf("default ver:0x%x\r\n",temp[0]);
|
|
||||||
if (temp[0] < 0X61) //默认版本比较低,需要更新flash配置
|
|
||||||
{
|
|
||||||
gt9147_send_cfg(1); //更新并保存配置
|
|
||||||
}
|
|
||||||
swm_delay(10);
|
|
||||||
temp[0] = 0x00;
|
|
||||||
gt9147_write_reg(GT_CTRL_REG, temp, 1); //结束复位
|
|
||||||
|
|
||||||
// swm_delay(100);
|
|
||||||
// gt9147_read_reg(GT_CFGS_REG, temp, 186);
|
|
||||||
// printf("read register: ");
|
|
||||||
// for (uint32_t i = 0; i < 186; i++)
|
|
||||||
// {
|
|
||||||
// if ((i % 10) == 0)
|
|
||||||
// {
|
|
||||||
// printf("\r\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// printf("0x%x,", temp[i]);
|
|
||||||
// }
|
|
||||||
// printf("\r\n");
|
|
||||||
|
|
||||||
timer_init(&tp_dev.timer, 100, gt9147_scan, LOOP_FOREVER, NULL);
|
|
||||||
timer_start(&tp_dev.timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint16_t GT9147_TPX_TBL[5] = {GT_TP1_REG, GT_TP2_REG, GT_TP3_REG, GT_TP4_REG, GT_TP5_REG};
|
|
||||||
//扫描触摸屏(采用查询方式)
|
|
||||||
void gt9147_scan(void)
|
|
||||||
{
|
|
||||||
uint8_t buf[4], touch_status = 0;
|
|
||||||
uint8_t temp;
|
|
||||||
uint8_t tempsta;
|
|
||||||
|
|
||||||
gt9147_read_reg(GT_GSTID_REG, &touch_status, 1); //读取触摸点的状态
|
|
||||||
if (touch_status & 0x80 && ((touch_status & 0x0F) < 6))
|
|
||||||
{
|
|
||||||
temp = 0;
|
|
||||||
gt9147_write_reg(GT_GSTID_REG, &temp, 1); //清标志
|
|
||||||
}
|
|
||||||
if ((touch_status & 0x0F) && ((touch_status & 0x0F) < 6))
|
|
||||||
{
|
|
||||||
temp = 0xFF << (touch_status & 0x0F); //将点的个数转换为1的位数,匹配tp_dev.sta定义
|
|
||||||
tempsta = tp_dev.sta; //保存当前的tp_dev.sta值
|
|
||||||
tp_dev.sta = (~temp) | TP_PRES_DOWN;
|
|
||||||
tp_dev.x[4] = tp_dev.x[0]; //保存触点0的数据
|
|
||||||
tp_dev.y[4] = tp_dev.y[0];
|
|
||||||
for (uint32_t i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
if (tp_dev.sta & (1 << i)) //触摸有效?
|
|
||||||
{
|
|
||||||
swm_delay(5);
|
|
||||||
gt9147_read_reg(GT9147_TPX_TBL[i], buf, 4); //读取XY坐标值
|
|
||||||
tp_dev.x[i] = (((uint16_t)buf[1] << 8) + buf[0]);
|
|
||||||
tp_dev.y[i] = (((uint16_t)buf[3] << 8) + buf[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tp_dev.x[0] > LV_HOR_RES_MAX || tp_dev.y[0] > LV_VER_RES_MAX) //非法数据(坐标超出了)
|
|
||||||
{
|
|
||||||
if ((touch_status & 0x0F) > 1) //有其他点有数据,则复第二个触点的数据到第一个触点.
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = tp_dev.x[1];
|
|
||||||
tp_dev.y[0] = tp_dev.y[1];
|
|
||||||
}
|
|
||||||
else //非法数据,则忽略此次数据(还原原来的)
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = tp_dev.x[4];
|
|
||||||
tp_dev.y[0] = tp_dev.y[4];
|
|
||||||
touch_status = 0x80;
|
|
||||||
tp_dev.sta = tempsta; //恢复tp_dev.sta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((touch_status & 0x8F) == 0x80) //无触摸点按下
|
|
||||||
{
|
|
||||||
if (tp_dev.sta & TP_PRES_DOWN) //之前是被按下的
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = 0xffff;
|
|
||||||
tp_dev.y[0] = 0xffff;
|
|
||||||
tp_dev.sta &= ~(1 << 7); //标记按键松开
|
|
||||||
}
|
|
||||||
else //之前就没有被按下
|
|
||||||
{
|
|
||||||
tp_dev.x[0] = 0xffff;
|
|
||||||
tp_dev.y[0] = 0xffff;
|
|
||||||
tp_dev.sta &= 0XE0; //清除点有效标记
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
#ifndef __DEV_GT9147_H__
|
|
||||||
#define __DEV_GT9147_H__
|
|
||||||
|
|
||||||
#include "SWM320.h"
|
|
||||||
#include "dev_systick.h"
|
|
||||||
|
|
||||||
/*复位引脚*/
|
|
||||||
#define GPIO_GT_RST GPIOC
|
|
||||||
#define PIN_GT_RST PIN4
|
|
||||||
/*中断引脚*/
|
|
||||||
#define GPIO_GT_INT GPIOC
|
|
||||||
#define PIN_GT_INT PIN5
|
|
||||||
//I2C读写命令
|
|
||||||
//#define GT_CMD_WR 0x28 //写命令
|
|
||||||
//#define GT_CMD_RD 0x29 //读命令
|
|
||||||
#define GT_CMD_WR 0xBA //写命令
|
|
||||||
#define GT_CMD_RD 0xBB //读命令
|
|
||||||
//GT9147 部分寄存器定义
|
|
||||||
#define GT_CTRL_REG 0x8040 //GT9147控制寄存器
|
|
||||||
#define GT_CFGS_REG 0x8047 //GT9147配置起始地址寄存器
|
|
||||||
#define GT_CHECK_REG 0x80FF //GT9147校验和寄存器
|
|
||||||
#define GT_PID_REG 0x8140 //GT9147产品ID寄存器
|
|
||||||
|
|
||||||
#define GT_GSTID_REG 0x814E //GT9147当前检测到的触摸情况
|
|
||||||
#define GT_TP1_REG 0x8150 //第一个触摸点数据地址
|
|
||||||
#define GT_TP2_REG 0x8158 //第二个触摸点数据地址
|
|
||||||
#define GT_TP3_REG 0x8160 //第三个触摸点数据地址
|
|
||||||
#define GT_TP4_REG 0x8168 //第四个触摸点数据地址
|
|
||||||
#define GT_TP5_REG 0x8170 //第五个触摸点数据地址
|
|
||||||
|
|
||||||
#define TP_PRES_DOWN 0x80 //触屏被按下
|
|
||||||
#define CT_MAX_TOUCH 5 //电容屏支持的点数,固定为5点
|
|
||||||
|
|
||||||
//触摸屏控制器
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t x[CT_MAX_TOUCH]; //当前坐标
|
|
||||||
uint16_t y[CT_MAX_TOUCH]; //电容屏有最多5组坐标
|
|
||||||
uint8_t sta; //笔的状态
|
|
||||||
//b7:按下1/松开0;
|
|
||||||
//b6~b5:保留
|
|
||||||
//b4~b0:电容触摸屏按下的点数(0,表示未按下,1表示按下)
|
|
||||||
struct Timer timer;
|
|
||||||
} _m_tp_dev;
|
|
||||||
|
|
||||||
extern _m_tp_dev tp_dev;
|
|
||||||
|
|
||||||
void gt9147_init(void);
|
|
||||||
void gt9147_scan(void);
|
|
||||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
#include "lv_conf.h"
|
|
||||||
|
|
||||||
void lcd_memory_init(void)
|
|
||||||
{
|
|
||||||
SDRAM_InitStructure SDRAM_InitStruct;
|
|
||||||
|
|
||||||
PORT->PORTP_SEL0 = 0xAAAAAAAA; //PP0-23 => ADDR0-23
|
|
||||||
PORT->PORTP_SEL1 &= ~0x00000F0F;
|
|
||||||
PORT->PORTP_SEL1 |= 0x00000A0A;
|
|
||||||
|
|
||||||
PORT->PORTM_SEL0 = 0xAAAAAAAA; //PM0-15 => DATA15-0
|
|
||||||
PORT->PORTM_INEN = 0xFFFF;
|
|
||||||
//PM16 => OEN,PM17 => WEN,PM18 => NORFL_CSN,PM19 => SDRAM_CSN,PM20 => SRAM_CSN,PM21 => SDRAM_CKE
|
|
||||||
PORT->PORTM_SEL1 = 0x888;
|
|
||||||
|
|
||||||
SDRAM_InitStruct.CellSize = SDRAM_CELLSIZE_64Mb;
|
|
||||||
SDRAM_InitStruct.CellBank = SDRAM_CELLBANK_4;
|
|
||||||
SDRAM_InitStruct.CellWidth = SDRAM_CELLWIDTH_16;
|
|
||||||
SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_2;
|
|
||||||
SDRAM_InitStruct.TimeTMRD = SDRAM_TMRD_3;
|
|
||||||
SDRAM_InitStruct.TimeTRRD = SDRAM_TRRD_2;
|
|
||||||
SDRAM_InitStruct.TimeTRAS = SDRAM_TRAS_6;
|
|
||||||
SDRAM_InitStruct.TimeTRC = SDRAM_TRC_8;
|
|
||||||
SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_3;
|
|
||||||
SDRAM_InitStruct.TimeTRP = SDRAM_TRP_3;
|
|
||||||
SDRAM_Init(&SDRAM_InitStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcd_rgb_init(void)
|
|
||||||
{
|
|
||||||
LCD_InitStructure LCD_initStruct;
|
|
||||||
|
|
||||||
GPIO_Init(GPIOM, PIN20, 1, 0, 0); //复位
|
|
||||||
GPIO_ClrBit(GPIOM, PIN20);
|
|
||||||
swm_delay(1);
|
|
||||||
GPIO_SetBit(GPIOM, PIN20);
|
|
||||||
|
|
||||||
GPIO_Init(GPIOB, PIN12, 1, 0, 0); //背光控制
|
|
||||||
GPIO_SetBit(GPIOB, PIN12); //点亮背光
|
|
||||||
|
|
||||||
PORT->PORTN_SEL0 = 0xAAAAAAAA; //GPION.0~15 LCD_DATA0~15
|
|
||||||
PORT->PORTN_SEL1 = 0xAA;
|
|
||||||
|
|
||||||
LCD_initStruct.Interface = LCD_INTERFACE_RGB;
|
|
||||||
LCD_initStruct.HnPixel = LV_VER_RES_MAX;
|
|
||||||
LCD_initStruct.VnPixel = LV_HOR_RES_MAX;
|
|
||||||
LCD_initStruct.Hfp = 5;
|
|
||||||
LCD_initStruct.Hbp = 40;
|
|
||||||
LCD_initStruct.Vfp = 8;
|
|
||||||
LCD_initStruct.Vbp = 8;
|
|
||||||
LCD_initStruct.ClkDiv = LCD_CLKDIV_8;
|
|
||||||
LCD_initStruct.ClkAlways = 0;
|
|
||||||
LCD_initStruct.SamplEdge = LCD_SAMPLEDGE_FALL;
|
|
||||||
LCD_initStruct.HsyncWidth = LCD_HSYNC_1DOTCLK;
|
|
||||||
LCD_initStruct.IntEOTEn = 1;
|
|
||||||
LCD_Init(LCD, &LCD_initStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_Handler(void)
|
|
||||||
{
|
|
||||||
LCD_INTClr(LCD);
|
|
||||||
LCD_Start(LCD);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef __DEV_RGBLCD_H__
|
|
||||||
#define __DEV_RGBLCD_H__
|
|
||||||
|
|
||||||
void lcd_memory_init(void);
|
|
||||||
void lcd_rgb_init(void);
|
|
||||||
|
|
||||||
#endif //__DEV_RGBLCD_H__
|
|
@ -1,12 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
|
|
||||||
uint32_t sdcard_init(void)
|
|
||||||
{
|
|
||||||
PORT_Init(PORTB, PIN1, PORTB_PIN1_SD_CLK, 0);
|
|
||||||
PORT_Init(PORTB, PIN2, PORTB_PIN2_SD_CMD, 1);
|
|
||||||
PORT_Init(PORTB, PIN3, PORTB_PIN3_SD_D0, 1);
|
|
||||||
PORT_Init(PORTB, PIN4, PORTB_PIN4_SD_D1, 1);
|
|
||||||
PORT_Init(PORTB, PIN5, PORTB_PIN5_SD_D2, 1);
|
|
||||||
PORT_Init(PORTB, PIN6, PORTB_PIN6_SD_D3, 1);
|
|
||||||
return SDIO_Init(30000000);
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef __SDCARD_H__
|
|
||||||
#define __SDCARD_H__
|
|
||||||
|
|
||||||
#include "swm320.h"
|
|
||||||
|
|
||||||
uint32_t sdcard_init(void);
|
|
||||||
|
|
||||||
#endif //__SDCARD_H__
|
|
@ -1,40 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
|
|
||||||
//Timer ticks
|
|
||||||
static __IO uint32_t systick = 0;
|
|
||||||
|
|
||||||
void systick_init(void)
|
|
||||||
{
|
|
||||||
/* SystemFrequency / 1000 1ms中断一次
|
|
||||||
* SystemFrequency / 100000 10us中断一次
|
|
||||||
* SystemFrequency / 1000000 1us中断一次
|
|
||||||
*/
|
|
||||||
if (SysTick_Config(SystemCoreClock / 1000))
|
|
||||||
{
|
|
||||||
/* Capture error */
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void swm_inctick(void)
|
|
||||||
{
|
|
||||||
systick++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t swm_gettick(void)
|
|
||||||
{
|
|
||||||
return systick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swm_delay(__IO uint32_t delay)
|
|
||||||
{
|
|
||||||
uint32_t tickstart = 0;
|
|
||||||
tickstart = swm_gettick();
|
|
||||||
while ((swm_gettick() - tickstart) < delay)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************END OF FILE**********************/
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef __DEV_SYSTICK_H__
|
|
||||||
#define __DEV_SYSTICK_H__
|
|
||||||
|
|
||||||
void systick_init(void);
|
|
||||||
void swm_inctick(void);
|
|
||||||
void swm_delay(__IO uint32_t delay);
|
|
||||||
|
|
||||||
#endif //__DEV_SYSTICK_H__
|
|
@ -1,37 +0,0 @@
|
|||||||
#include "SWM320.h"
|
|
||||||
|
|
||||||
void serial_init(void)
|
|
||||||
{
|
|
||||||
UART_InitStructure UART_initStruct;
|
|
||||||
|
|
||||||
PORT_Init(PORTC, PIN2, FUNMUX0_UART0_RXD, 1); //GPIOC.2配置为UART0输入引脚
|
|
||||||
PORT_Init(PORTC, PIN3, FUNMUX1_UART0_TXD, 0); //GPIOC.3配置为UART0输出引脚
|
|
||||||
|
|
||||||
UART_initStruct.Baudrate = 115200;
|
|
||||||
UART_initStruct.DataBits = UART_DATA_8BIT;
|
|
||||||
UART_initStruct.Parity = UART_PARITY_NONE;
|
|
||||||
UART_initStruct.StopBits = UART_STOP_1BIT;
|
|
||||||
UART_initStruct.RXThresholdIEn = 0;
|
|
||||||
UART_initStruct.TXThresholdIEn = 0;
|
|
||||||
UART_initStruct.TimeoutIEn = 0;
|
|
||||||
UART_Init(UART0, &UART_initStruct);
|
|
||||||
UART_Open(UART0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************************************************************************
|
|
||||||
* 函数名称: fputc()
|
|
||||||
* 功能说明: printf()使用此函数完成实际的串口打印动作
|
|
||||||
* 输 入: int ch 要打印的字符
|
|
||||||
* FILE *f 文件句柄
|
|
||||||
* 输 出: 无
|
|
||||||
* 注意事项: 无
|
|
||||||
******************************************************************************************************************************************/
|
|
||||||
int fputc(int ch, FILE *f)
|
|
||||||
{
|
|
||||||
UART_WriteByte(UART0, ch);
|
|
||||||
|
|
||||||
while (UART_IsTXBusy(UART0))
|
|
||||||
;
|
|
||||||
|
|
||||||
return ch;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef __DEV_UART_H__
|
|
||||||
#define __DEV_UART_H__
|
|
||||||
|
|
||||||
void serial_init(void);
|
|
||||||
|
|
||||||
#endif //__DEV_UART_H__
|
|
@ -1,233 +0,0 @@
|
|||||||
#include "main.h"
|
|
||||||
#include "lvgl.h"
|
|
||||||
#include "lv_port_disp.h"
|
|
||||||
#include "ff.h"
|
|
||||||
#include "sfud.h"
|
|
||||||
|
|
||||||
/* 桌面图片变量定义 */
|
|
||||||
lv_img_dsc_t bin_wallpaper;
|
|
||||||
|
|
||||||
/* user_img 描述信息结构体 */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
lv_img_dsc_t *icon_img; /* 图片变量的指针 */
|
|
||||||
const char *icon_fname; /* 文件名 */
|
|
||||||
|
|
||||||
} user_img_item;
|
|
||||||
|
|
||||||
static const user_img_item user_img[] =
|
|
||||||
{
|
|
||||||
//wallpaper
|
|
||||||
{&bin_wallpaper, "P:0:/wp1_ver.bin"},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
FRESULT sdcard2spiflash(const char *psrc, const char *pdst) //真正搬运数据用到的函数
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
uint16_t br = 0;
|
|
||||||
uint16_t bw = 0;
|
|
||||||
FIL fsrc;
|
|
||||||
FIL fdst;
|
|
||||||
uint8_t tempbuf[4096];
|
|
||||||
|
|
||||||
res = f_open(&fsrc, (const TCHAR *)psrc, FA_READ | FA_OPEN_EXISTING); //打开只读文件
|
|
||||||
if (res == FR_OK)
|
|
||||||
res = f_open(&fdst, (const TCHAR *)pdst, FA_WRITE | FA_CREATE_ALWAYS); //第一个打开成功,才开始打开第二个
|
|
||||||
if (res == FR_OK) //两个都打开成功了
|
|
||||||
{
|
|
||||||
while (res == 0) //开始复制
|
|
||||||
{
|
|
||||||
res = f_read(&fsrc, tempbuf, 4096, (UINT *)&br); //源头读出512字节
|
|
||||||
if (res || br == 0)
|
|
||||||
break;
|
|
||||||
res = f_write(&fdst, tempbuf, (UINT)br, (UINT *)&bw); //写入目的文件
|
|
||||||
if (res || bw < br)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
f_close(&fsrc);
|
|
||||||
f_close(&fdst);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_files(void)
|
|
||||||
{
|
|
||||||
FATFS sdcard_fs;
|
|
||||||
FATFS flash_fs;
|
|
||||||
if (f_mount(&sdcard_fs, "1:", 1) != FR_OK) //sdcard挂载失败认为未插入sdcard
|
|
||||||
{
|
|
||||||
if (f_mount(&flash_fs, "0:", 1) != FR_OK) //spiflash也挂载失败,说明spiflash未格式化,需要插入sdcard来格式化spiflash
|
|
||||||
{
|
|
||||||
debugerror("spi flash mount error.\r\n");
|
|
||||||
lv_obj_t *label_info = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
lv_label_set_text(label_info, LV_SYMBOL_WARNING "spi flash mount error.\nPlease insert an SD Card and try again.");
|
|
||||||
lv_obj_align(label_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //sdcard挂载成功则格式化spiflash,拷贝相应文件到spiflash
|
|
||||||
{
|
|
||||||
BYTE work[FF_MAX_SS];
|
|
||||||
if (f_mkfs("0:", FM_ANY, 0, work, sizeof work) != FR_OK) //格式化spiflash
|
|
||||||
{
|
|
||||||
debugerror("spi flash formatting error.\r\n");
|
|
||||||
lv_obj_t *label_info = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
lv_label_set_text(label_info, LV_SYMBOL_WARNING "spi flash formatting error.");
|
|
||||||
lv_obj_align(label_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (f_mount(&flash_fs, "0:", 1) != FR_OK) //挂载spiflash
|
|
||||||
{
|
|
||||||
debugerror("spi flash mount error.\r\n");
|
|
||||||
lv_obj_t *label_info = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
lv_label_set_text(label_info, LV_SYMBOL_WARNING "spi flash mount error.");
|
|
||||||
lv_obj_align(label_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char psrc[64] = {"1:/yahei11.bin"}, pdst[64] = {"0:/yahei11.bin"};
|
|
||||||
|
|
||||||
lv_obj_t *label_copy_head = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
lv_obj_t *label_copy_info = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
lv_label_set_text(label_copy_head, "sdcard,spiflash ok,copying files");
|
|
||||||
lv_obj_align(label_copy_head, NULL, LV_ALIGN_CENTER, 0, -20);
|
|
||||||
// debug("%s\r\n", psrc);
|
|
||||||
// lv_label_set_text(label_copy_info, psrc);
|
|
||||||
// lv_obj_align(label_copy_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
// lv_task_handler();
|
|
||||||
// gui2show();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sizeof(user_img) / sizeof(user_img[0]); i++)
|
|
||||||
{
|
|
||||||
strcpy(psrc, "1");
|
|
||||||
strcpy(pdst, "0");
|
|
||||||
strcat(psrc, &(user_img[i].icon_fname[3]));
|
|
||||||
strcat(pdst, &(user_img[i].icon_fname[3]));
|
|
||||||
// debug("psrc %s\r\n", psrc);
|
|
||||||
// debug("pdst %s\r\n", pdst);
|
|
||||||
|
|
||||||
lv_label_set_text(label_copy_info, psrc);
|
|
||||||
lv_obj_align(label_copy_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
|
|
||||||
if (sdcard2spiflash(psrc, pdst) != FR_OK)
|
|
||||||
{
|
|
||||||
lv_label_set_text(label_copy_info, LV_SYMBOL_WARNING "sdcard to spi flash error.");
|
|
||||||
lv_obj_align(label_copy_info, NULL, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lv_obj_del(label_copy_head);
|
|
||||||
lv_obj_del(label_copy_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t resource_addr = SDRAMM_BASE + 1024 * 1024; //从SDRAM内存的1M处开始存放,先存字体,再存图片
|
|
||||||
/**
|
|
||||||
* @brief 从文件系统获取bmp图片
|
|
||||||
* @param image-存储图片信息的指针
|
|
||||||
* @param file_name-文件名
|
|
||||||
* @retval 0-加载成功 非0-加载失败
|
|
||||||
*/
|
|
||||||
uint8_t lv_load_img_bin_from_file(lv_img_dsc_t *image, const char *file_name)
|
|
||||||
{
|
|
||||||
lv_fs_file_t sd_file;
|
|
||||||
lv_fs_res_t lv_fs_res = LV_FS_RES_OK;
|
|
||||||
uint32_t file_size;
|
|
||||||
uint32_t temp; //读取数据缓冲
|
|
||||||
uint32_t br;
|
|
||||||
uint32_t header;
|
|
||||||
|
|
||||||
if (image == NULL)
|
|
||||||
return 1;
|
|
||||||
if (file_name == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
lv_fs_res = lv_fs_open(&sd_file, file_name, LV_FS_MODE_RD);
|
|
||||||
if (lv_fs_res != LV_FS_RES_OK)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lv_fs_size(&sd_file, &file_size);
|
|
||||||
// debug("file name %s, size %d\r\n",file_name,file_size);
|
|
||||||
if (file_size > LV_HOR_RES * LV_VER_RES * 4)
|
|
||||||
{
|
|
||||||
/* 文件过大了 */
|
|
||||||
lv_fs_close(&sd_file);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_fs_res = lv_fs_read(&sd_file, &temp, 4, &br);
|
|
||||||
if ((lv_fs_res != LV_FS_RES_OK) || (br == 0))
|
|
||||||
{
|
|
||||||
lv_fs_close(&sd_file);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
/* 获取头 */
|
|
||||||
header = temp;
|
|
||||||
// debug("header:0X%X\r\n",header);
|
|
||||||
// debug("width:%d height:%d\r\n", (uint16_t)(header >> 10) & 0x7ff, header >> 21);
|
|
||||||
image->header.cf = header & 0x1F;
|
|
||||||
image->header.always_zero = 0;
|
|
||||||
image->header.w = (uint16_t)(header >> 10) & 0x7FF;
|
|
||||||
image->header.h = (uint16_t)(header >> 21);
|
|
||||||
image->data_size = file_size - 4; //去掉4字节的头,剩余的就是图片数据流长度
|
|
||||||
image->data = (const uint8_t *)resource_addr;
|
|
||||||
|
|
||||||
//图片bin文件为4字节图片结构体+rgb数据,保证图片长宽为偶数
|
|
||||||
for (uint32_t i = 0; i < file_size / 4; i++)
|
|
||||||
{
|
|
||||||
lv_fs_res = lv_fs_read(&sd_file, &temp, 4, &br);
|
|
||||||
if ((lv_fs_res != LV_FS_RES_OK) || (br == 0))
|
|
||||||
{
|
|
||||||
lv_fs_close(&sd_file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*(uint32_t *)resource_addr = temp;
|
|
||||||
resource_addr += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_fs_close(&sd_file);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从文件系统加载所有图片到内存
|
|
||||||
* @param None
|
|
||||||
* @retval 0-加载成功 非0-加载失败
|
|
||||||
*/
|
|
||||||
uint8_t lv_load_user_img_from_file(void)
|
|
||||||
{
|
|
||||||
lv_obj_t *label_info = lv_label_create(lv_scr_act(), NULL);
|
|
||||||
for (uint32_t i = 0; i < sizeof(user_img) / sizeof(user_img[0]); i++)
|
|
||||||
{
|
|
||||||
if (lv_load_img_bin_from_file(user_img[i].icon_img, user_img[i].icon_fname) != 0)
|
|
||||||
return 1;
|
|
||||||
lv_label_set_text(label_info, user_img[i].icon_fname);
|
|
||||||
lv_obj_align(label_info, NULL, LV_ALIGN_CENTER, 0, 40);
|
|
||||||
lv_task_handler();
|
|
||||||
gui2show();
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_del(label_info);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef __LOAD_H__
|
|
||||||
#define __LOAD_H__
|
|
||||||
|
|
||||||
extern uint32_t resource_addr;
|
|
||||||
|
|
||||||
/* 桌面图片变量定义 */
|
|
||||||
extern lv_img_dsc_t bin_wallpaper;
|
|
||||||
extern lv_img_dsc_t bin_wallpaper_chip;
|
|
||||||
extern lv_img_dsc_t bin_evernote;
|
|
||||||
extern lv_img_dsc_t bin_facebook;
|
|
||||||
extern lv_img_dsc_t bin_google;
|
|
||||||
extern lv_img_dsc_t bin_message;
|
|
||||||
extern lv_img_dsc_t bin_skype;
|
|
||||||
extern lv_img_dsc_t bin_twitter;
|
|
||||||
extern lv_img_dsc_t bin_avi;
|
|
||||||
extern lv_img_dsc_t bin_gif;
|
|
||||||
extern lv_img_dsc_t bin_back;
|
|
||||||
|
|
||||||
void load_files(void);
|
|
||||||
uint8_t lv_load_user_img_from_file(void);
|
|
||||||
#endif //__LOAD_H__
|
|
@ -1,765 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_conf.h
|
|
||||||
* Configuration file for v8.3.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy this file as `lv_conf.h`
|
|
||||||
* 1. simply next to the `lvgl` folder
|
|
||||||
* 2. or any other places and
|
|
||||||
* - define `LV_CONF_INCLUDE_SIMPLE`
|
|
||||||
* - add the path as include path
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
#if 1 /*Set it to "1" to enable content*/
|
|
||||||
|
|
||||||
#ifndef LV_CONF_H
|
|
||||||
#define LV_CONF_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* ===================
|
|
||||||
MY SETTINGS
|
|
||||||
*====================*/
|
|
||||||
#define LV_HOR_RES_MAX (272)
|
|
||||||
#define LV_VER_RES_MAX (480)
|
|
||||||
|
|
||||||
/*====================
|
|
||||||
COLOR SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
|
|
||||||
#define LV_COLOR_DEPTH 16
|
|
||||||
|
|
||||||
/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
|
|
||||||
#define LV_COLOR_16_SWAP 0
|
|
||||||
|
|
||||||
/*Enable features to draw on transparent background.
|
|
||||||
*It's required if opa, and transform_* style properties are used.
|
|
||||||
*Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/
|
|
||||||
#define LV_COLOR_SCREEN_TRANSP 0
|
|
||||||
|
|
||||||
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
|
|
||||||
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
|
|
||||||
#define LV_COLOR_MIX_ROUND_OFS 0
|
|
||||||
|
|
||||||
/*Images pixels with this color will not be drawn if they are chroma keyed)*/
|
|
||||||
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/
|
|
||||||
|
|
||||||
/*=========================
|
|
||||||
MEMORY SETTINGS
|
|
||||||
*=========================*/
|
|
||||||
|
|
||||||
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
|
|
||||||
#define LV_MEM_CUSTOM 0
|
|
||||||
#if LV_MEM_CUSTOM == 0
|
|
||||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
|
||||||
#define LV_MEM_SIZE (48U * 1024U) /*[bytes]*/
|
|
||||||
|
|
||||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
|
||||||
#define LV_MEM_ADR 0 /*0: unused*/
|
|
||||||
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
|
|
||||||
#if LV_MEM_ADR == 0
|
|
||||||
#undef LV_MEM_POOL_INCLUDE
|
|
||||||
#undef LV_MEM_POOL_ALLOC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /*LV_MEM_CUSTOM*/
|
|
||||||
#define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
|
||||||
#define LV_MEM_CUSTOM_ALLOC malloc
|
|
||||||
#define LV_MEM_CUSTOM_FREE free
|
|
||||||
#define LV_MEM_CUSTOM_REALLOC realloc
|
|
||||||
#endif /*LV_MEM_CUSTOM*/
|
|
||||||
|
|
||||||
/*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms.
|
|
||||||
*You will see an error log message if there wasn't enough buffers. */
|
|
||||||
#define LV_MEM_BUF_MAX_NUM 16
|
|
||||||
|
|
||||||
/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/
|
|
||||||
#define LV_MEMCPY_MEMSET_STD 0
|
|
||||||
|
|
||||||
/*====================
|
|
||||||
HAL SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
|
||||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
|
||||||
|
|
||||||
/*Input device read period in milliseconds*/
|
|
||||||
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/
|
|
||||||
|
|
||||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
|
||||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
|
||||||
#define LV_TICK_CUSTOM 0
|
|
||||||
#if LV_TICK_CUSTOM
|
|
||||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
|
||||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
|
||||||
#endif /*LV_TICK_CUSTOM*/
|
|
||||||
|
|
||||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
|
||||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
|
||||||
#define LV_DPI_DEF 100 /*[px/inch]*/
|
|
||||||
|
|
||||||
/*=======================
|
|
||||||
* FEATURE CONFIGURATION
|
|
||||||
*=======================*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Drawing
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable complex draw engine.
|
|
||||||
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
|
|
||||||
#define LV_DRAW_COMPLEX 1
|
|
||||||
#if LV_DRAW_COMPLEX != 0
|
|
||||||
|
|
||||||
/*Allow buffering some shadow calculation.
|
|
||||||
*LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
|
|
||||||
*Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
|
||||||
#define LV_SHADOW_CACHE_SIZE 0
|
|
||||||
|
|
||||||
/* Set number of maximally cached circle data.
|
|
||||||
* The circumference of 1/4 circle are saved for anti-aliasing
|
|
||||||
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
|
|
||||||
* 0: to disable caching */
|
|
||||||
#define LV_CIRCLE_CACHE_SIZE 4
|
|
||||||
#endif /*LV_DRAW_COMPLEX*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer
|
|
||||||
* and blend it as an image with the given opacity.
|
|
||||||
* Note that `bg_opa`, `text_opa` etc don't require buffering into layer)
|
|
||||||
* The widget can be buffered in smaller chunks to avoid using large buffers.
|
|
||||||
*
|
|
||||||
* - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it
|
|
||||||
* - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated.
|
|
||||||
*
|
|
||||||
* Both buffer sizes are in bytes.
|
|
||||||
* "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers
|
|
||||||
* and can't be drawn in chunks. So these settings affects only widgets with opacity.
|
|
||||||
*/
|
|
||||||
#define LV_LAYER_SIMPLE_BUF_SIZE (24 * 1024)
|
|
||||||
#define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024)
|
|
||||||
|
|
||||||
/*Default image cache size. Image caching keeps the images opened.
|
|
||||||
*If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added)
|
|
||||||
*With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
|
||||||
*However the opened images might consume additional RAM.
|
|
||||||
*0: to disable caching*/
|
|
||||||
#define LV_IMG_CACHE_DEF_SIZE 0
|
|
||||||
|
|
||||||
/*Number of stops allowed per gradient. Increase this to allow more stops.
|
|
||||||
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
|
|
||||||
#define LV_GRADIENT_MAX_STOPS 2
|
|
||||||
|
|
||||||
/*Default gradient buffer size.
|
|
||||||
*When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
|
|
||||||
*LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
|
|
||||||
*If the cache is too small the map will be allocated only while it's required for the drawing.
|
|
||||||
*0 mean no caching.*/
|
|
||||||
#define LV_GRAD_CACHE_DEF_SIZE 0
|
|
||||||
|
|
||||||
/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
|
|
||||||
*LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
|
|
||||||
*The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
|
|
||||||
#define LV_DITHER_GRADIENT 0
|
|
||||||
#if LV_DITHER_GRADIENT
|
|
||||||
/*Add support for error diffusion dithering.
|
|
||||||
*Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
|
|
||||||
*The increase in memory consumption is (24 bits * object's width)*/
|
|
||||||
#define LV_DITHER_ERROR_DIFFUSION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Maximum buffer size to allocate for rotation.
|
|
||||||
*Only used if software rotation is enabled in the display driver.*/
|
|
||||||
#define LV_DISP_ROT_MAX_BUF (10*1024)
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* GPU
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Use Arm's 2D acceleration library Arm-2D */
|
|
||||||
#define LV_USE_GPU_ARM2D 0
|
|
||||||
|
|
||||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
|
||||||
#define LV_USE_GPU_STM32_DMA2D 0
|
|
||||||
#if LV_USE_GPU_STM32_DMA2D
|
|
||||||
/*Must be defined to include path of CMSIS header of target processor
|
|
||||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
|
||||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use SWM341's DMA2D GPU*/
|
|
||||||
#define LV_USE_GPU_SWM341_DMA2D 0
|
|
||||||
#if LV_USE_GPU_SWM341_DMA2D
|
|
||||||
#define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use NXP's PXP GPU iMX RTxxx platforms*/
|
|
||||||
#define LV_USE_GPU_NXP_PXP 0
|
|
||||||
#if LV_USE_GPU_NXP_PXP
|
|
||||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
|
||||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
|
||||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
|
||||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
|
||||||
*/
|
|
||||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use NXP's VG-Lite GPU iMX RTxxx platforms*/
|
|
||||||
#define LV_USE_GPU_NXP_VG_LITE 0
|
|
||||||
|
|
||||||
/*Use SDL renderer API*/
|
|
||||||
#define LV_USE_GPU_SDL 0
|
|
||||||
#if LV_USE_GPU_SDL
|
|
||||||
#define LV_GPU_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
|
||||||
/*Texture cache size, 8MB by default*/
|
|
||||||
#define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8)
|
|
||||||
/*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/
|
|
||||||
#define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Logging
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable the log module*/
|
|
||||||
#define LV_USE_LOG 0
|
|
||||||
#if LV_USE_LOG
|
|
||||||
|
|
||||||
/*How important log should be added:
|
|
||||||
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
|
||||||
*LV_LOG_LEVEL_INFO Log important events
|
|
||||||
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
|
||||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
|
||||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
|
||||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
|
||||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
|
||||||
|
|
||||||
/*1: Print the log with 'printf';
|
|
||||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
|
||||||
#define LV_LOG_PRINTF 0
|
|
||||||
|
|
||||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
|
||||||
#define LV_LOG_TRACE_MEM 1
|
|
||||||
#define LV_LOG_TRACE_TIMER 1
|
|
||||||
#define LV_LOG_TRACE_INDEV 1
|
|
||||||
#define LV_LOG_TRACE_DISP_REFR 1
|
|
||||||
#define LV_LOG_TRACE_EVENT 1
|
|
||||||
#define LV_LOG_TRACE_OBJ_CREATE 1
|
|
||||||
#define LV_LOG_TRACE_LAYOUT 1
|
|
||||||
#define LV_LOG_TRACE_ANIM 1
|
|
||||||
|
|
||||||
#endif /*LV_USE_LOG*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Asserts
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable asserts if an operation is failed or an invalid data is found.
|
|
||||||
*If LV_USE_LOG is enabled an error message will be printed on failure*/
|
|
||||||
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
|
||||||
#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
|
|
||||||
|
|
||||||
/*Add a custom handler when assert happens e.g. to restart the MCU*/
|
|
||||||
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
|
|
||||||
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Others
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*1: Show CPU usage and FPS count*/
|
|
||||||
#define LV_USE_PERF_MONITOR 0
|
|
||||||
#if LV_USE_PERF_MONITOR
|
|
||||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*1: Show the used memory and the memory fragmentation
|
|
||||||
* Requires LV_MEM_CUSTOM = 0*/
|
|
||||||
#define LV_USE_MEM_MONITOR 0
|
|
||||||
#if LV_USE_MEM_MONITOR
|
|
||||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*1: Draw random colored rectangles over the redrawn areas*/
|
|
||||||
#define LV_USE_REFR_DEBUG 0
|
|
||||||
|
|
||||||
/*Change the built in (v)snprintf functions*/
|
|
||||||
#define LV_SPRINTF_CUSTOM 0
|
|
||||||
#if LV_SPRINTF_CUSTOM
|
|
||||||
#define LV_SPRINTF_INCLUDE <stdio.h>
|
|
||||||
#define lv_snprintf snprintf
|
|
||||||
#define lv_vsnprintf vsnprintf
|
|
||||||
#else /*LV_SPRINTF_CUSTOM*/
|
|
||||||
#define LV_SPRINTF_USE_FLOAT 0
|
|
||||||
#endif /*LV_SPRINTF_CUSTOM*/
|
|
||||||
|
|
||||||
#define LV_USE_USER_DATA 1
|
|
||||||
|
|
||||||
/*Garbage Collector settings
|
|
||||||
*Used if lvgl is bound to higher level language and the memory is managed by that language*/
|
|
||||||
#define LV_ENABLE_GC 0
|
|
||||||
#if LV_ENABLE_GC != 0
|
|
||||||
#define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
|
||||||
#endif /*LV_ENABLE_GC*/
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* COMPILER SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*For big endian systems set to 1*/
|
|
||||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_tick_inc` function*/
|
|
||||||
#define LV_ATTRIBUTE_TICK_INC
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_timer_handler` function*/
|
|
||||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_disp_flush_ready` function*/
|
|
||||||
#define LV_ATTRIBUTE_FLUSH_READY
|
|
||||||
|
|
||||||
/*Required alignment size for buffers*/
|
|
||||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
|
|
||||||
|
|
||||||
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
|
|
||||||
* E.g. __attribute__((aligned(4)))*/
|
|
||||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
|
||||||
|
|
||||||
/*Attribute to mark large constant arrays for example font's bitmaps*/
|
|
||||||
#define LV_ATTRIBUTE_LARGE_CONST
|
|
||||||
|
|
||||||
/*Compiler prefix for a big array declaration in RAM*/
|
|
||||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
|
||||||
|
|
||||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
|
||||||
#define LV_ATTRIBUTE_FAST_MEM
|
|
||||||
|
|
||||||
/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
|
|
||||||
#define LV_ATTRIBUTE_DMA
|
|
||||||
|
|
||||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
|
||||||
*should also appear on LVGL binding API such as Micropython.*/
|
|
||||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
|
|
||||||
|
|
||||||
/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
|
|
||||||
#define LV_USE_LARGE_COORD 0
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* FONT USAGE
|
|
||||||
*===================*/
|
|
||||||
|
|
||||||
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
|
|
||||||
*https://fonts.google.com/specimen/Montserrat*/
|
|
||||||
#define LV_FONT_MONTSERRAT_8 0
|
|
||||||
#define LV_FONT_MONTSERRAT_10 0
|
|
||||||
#define LV_FONT_MONTSERRAT_12 0
|
|
||||||
#define LV_FONT_MONTSERRAT_14 1
|
|
||||||
#define LV_FONT_MONTSERRAT_16 0
|
|
||||||
#define LV_FONT_MONTSERRAT_18 0
|
|
||||||
#define LV_FONT_MONTSERRAT_20 0
|
|
||||||
#define LV_FONT_MONTSERRAT_22 0
|
|
||||||
#define LV_FONT_MONTSERRAT_24 0
|
|
||||||
#define LV_FONT_MONTSERRAT_26 0
|
|
||||||
#define LV_FONT_MONTSERRAT_28 0
|
|
||||||
#define LV_FONT_MONTSERRAT_30 0
|
|
||||||
#define LV_FONT_MONTSERRAT_32 0
|
|
||||||
#define LV_FONT_MONTSERRAT_34 0
|
|
||||||
#define LV_FONT_MONTSERRAT_36 0
|
|
||||||
#define LV_FONT_MONTSERRAT_38 0
|
|
||||||
#define LV_FONT_MONTSERRAT_40 0
|
|
||||||
#define LV_FONT_MONTSERRAT_42 0
|
|
||||||
#define LV_FONT_MONTSERRAT_44 0
|
|
||||||
#define LV_FONT_MONTSERRAT_46 0
|
|
||||||
#define LV_FONT_MONTSERRAT_48 0
|
|
||||||
|
|
||||||
/*Demonstrate special features*/
|
|
||||||
#define LV_FONT_MONTSERRAT_12_SUBPX 0
|
|
||||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
|
|
||||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/
|
|
||||||
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
|
|
||||||
|
|
||||||
/*Pixel perfect monospace fonts*/
|
|
||||||
#define LV_FONT_UNSCII_8 0
|
|
||||||
#define LV_FONT_UNSCII_16 0
|
|
||||||
|
|
||||||
/*Optionally declare custom fonts here.
|
|
||||||
*You can use these fonts as default font too and they will be available globally.
|
|
||||||
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
|
|
||||||
#define LV_FONT_CUSTOM_DECLARE
|
|
||||||
|
|
||||||
/*Always set a default font*/
|
|
||||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
|
||||||
|
|
||||||
/*Enable handling large font and/or fonts with a lot of characters.
|
|
||||||
*The limit depends on the font size, font face and bpp.
|
|
||||||
*Compiler error will be triggered if a font needs it.*/
|
|
||||||
#define LV_FONT_FMT_TXT_LARGE 0
|
|
||||||
|
|
||||||
/*Enables/disables support for compressed fonts.*/
|
|
||||||
#define LV_USE_FONT_COMPRESSED 0
|
|
||||||
|
|
||||||
/*Enable subpixel rendering*/
|
|
||||||
#define LV_USE_FONT_SUBPX 0
|
|
||||||
#if LV_USE_FONT_SUBPX
|
|
||||||
/*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/
|
|
||||||
#define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Enable drawing placeholders when glyph dsc is not found*/
|
|
||||||
#define LV_USE_FONT_PLACEHOLDER 1
|
|
||||||
|
|
||||||
/*=================
|
|
||||||
* TEXT SETTINGS
|
|
||||||
*=================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select a character encoding for strings.
|
|
||||||
* Your IDE or editor should have the same character encoding
|
|
||||||
* - LV_TXT_ENC_UTF8
|
|
||||||
* - LV_TXT_ENC_ASCII
|
|
||||||
*/
|
|
||||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
|
||||||
|
|
||||||
/*Can break (wrap) texts on these chars*/
|
|
||||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
|
||||||
|
|
||||||
/*If a word is at least this long, will break wherever "prettiest"
|
|
||||||
*To disable, set to a value <= 0*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
|
||||||
|
|
||||||
/*Minimum number of characters in a long word to put on a line before a break.
|
|
||||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
|
||||||
|
|
||||||
/*Minimum number of characters in a long word to put on a line after a break.
|
|
||||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
|
||||||
|
|
||||||
/*The control character to use for signalling text recoloring.*/
|
|
||||||
#define LV_TXT_COLOR_CMD "#"
|
|
||||||
|
|
||||||
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
|
|
||||||
*The direction will be processed according to the Unicode Bidirectional Algorithm:
|
|
||||||
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
|
||||||
#define LV_USE_BIDI 0
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
/*Set the default direction. Supported values:
|
|
||||||
*`LV_BASE_DIR_LTR` Left-to-Right
|
|
||||||
*`LV_BASE_DIR_RTL` Right-to-Left
|
|
||||||
*`LV_BASE_DIR_AUTO` detect texts base direction*/
|
|
||||||
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Enable Arabic/Persian processing
|
|
||||||
*In these languages characters should be replaced with an other form based on their position in the text*/
|
|
||||||
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* WIDGET USAGE
|
|
||||||
*================*/
|
|
||||||
|
|
||||||
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
|
|
||||||
|
|
||||||
#define LV_USE_ARC 1
|
|
||||||
|
|
||||||
#define LV_USE_BAR 1
|
|
||||||
|
|
||||||
#define LV_USE_BTN 1
|
|
||||||
|
|
||||||
#define LV_USE_BTNMATRIX 1
|
|
||||||
|
|
||||||
#define LV_USE_CANVAS 1
|
|
||||||
|
|
||||||
#define LV_USE_CHECKBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
|
|
||||||
|
|
||||||
#define LV_USE_IMG 1 /*Requires: lv_label*/
|
|
||||||
|
|
||||||
#define LV_USE_LABEL 1
|
|
||||||
#if LV_USE_LABEL
|
|
||||||
#define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
|
|
||||||
#define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_LINE 1
|
|
||||||
|
|
||||||
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
|
|
||||||
#if LV_USE_ROLLER
|
|
||||||
#define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
|
||||||
|
|
||||||
#define LV_USE_SWITCH 1
|
|
||||||
|
|
||||||
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
|
|
||||||
#if LV_USE_TEXTAREA != 0
|
|
||||||
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_TABLE 1
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* EXTRA COMPONENTS
|
|
||||||
*==================*/
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Widgets
|
|
||||||
*----------*/
|
|
||||||
#define LV_USE_ANIMIMG 1
|
|
||||||
|
|
||||||
#define LV_USE_CALENDAR 1
|
|
||||||
#if LV_USE_CALENDAR
|
|
||||||
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
|
||||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
|
||||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
|
|
||||||
#else
|
|
||||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
|
||||||
#define LV_USE_CALENDAR_HEADER_ARROW 1
|
|
||||||
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
|
|
||||||
#endif /*LV_USE_CALENDAR*/
|
|
||||||
|
|
||||||
#define LV_USE_CHART 1
|
|
||||||
|
|
||||||
#define LV_USE_COLORWHEEL 1
|
|
||||||
|
|
||||||
#define LV_USE_IMGBTN 1
|
|
||||||
|
|
||||||
#define LV_USE_KEYBOARD 1
|
|
||||||
|
|
||||||
#define LV_USE_LED 1
|
|
||||||
|
|
||||||
#define LV_USE_LIST 1
|
|
||||||
|
|
||||||
#define LV_USE_MENU 1
|
|
||||||
|
|
||||||
#define LV_USE_METER 1
|
|
||||||
|
|
||||||
#define LV_USE_MSGBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_SPAN 1
|
|
||||||
#if LV_USE_SPAN
|
|
||||||
/*A line text can contain maximum num of span descriptor */
|
|
||||||
#define LV_SPAN_SNIPPET_STACK_SIZE 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_SPINBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_SPINNER 1
|
|
||||||
|
|
||||||
#define LV_USE_TABVIEW 1
|
|
||||||
|
|
||||||
#define LV_USE_TILEVIEW 1
|
|
||||||
|
|
||||||
#define LV_USE_WIN 1
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Themes
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*A simple, impressive and very complete theme*/
|
|
||||||
#define LV_USE_THEME_DEFAULT 1
|
|
||||||
#if LV_USE_THEME_DEFAULT
|
|
||||||
|
|
||||||
/*0: Light mode; 1: Dark mode*/
|
|
||||||
#define LV_THEME_DEFAULT_DARK 0
|
|
||||||
|
|
||||||
/*1: Enable grow on press*/
|
|
||||||
#define LV_THEME_DEFAULT_GROW 1
|
|
||||||
|
|
||||||
/*Default transition time in [ms]*/
|
|
||||||
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
|
|
||||||
#endif /*LV_USE_THEME_DEFAULT*/
|
|
||||||
|
|
||||||
/*A very simple theme that is a good starting point for a custom theme*/
|
|
||||||
#define LV_USE_THEME_BASIC 1
|
|
||||||
|
|
||||||
/*A theme designed for monochrome displays*/
|
|
||||||
#define LV_USE_THEME_MONO 1
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Layouts
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*A layout similar to Flexbox in CSS.*/
|
|
||||||
#define LV_USE_FLEX 1
|
|
||||||
|
|
||||||
/*A layout similar to Grid in CSS.*/
|
|
||||||
#define LV_USE_GRID 1
|
|
||||||
|
|
||||||
/*---------------------
|
|
||||||
* 3rd party libraries
|
|
||||||
*--------------------*/
|
|
||||||
|
|
||||||
/*File system interfaces for common APIs */
|
|
||||||
|
|
||||||
/*API for fopen, fread, etc*/
|
|
||||||
#define LV_USE_FS_STDIO 0
|
|
||||||
#if LV_USE_FS_STDIO
|
|
||||||
#define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for open, read, etc*/
|
|
||||||
#define LV_USE_FS_POSIX 0
|
|
||||||
#if LV_USE_FS_POSIX
|
|
||||||
#define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for CreateFile, ReadFile, etc*/
|
|
||||||
#define LV_USE_FS_WIN32 0
|
|
||||||
#if LV_USE_FS_WIN32
|
|
||||||
#define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
|
|
||||||
#define LV_USE_FS_FATFS 0
|
|
||||||
#if LV_USE_FS_FATFS
|
|
||||||
#define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PNG decoder library*/
|
|
||||||
#define LV_USE_PNG 1
|
|
||||||
|
|
||||||
/*BMP decoder library*/
|
|
||||||
#define LV_USE_BMP 0
|
|
||||||
|
|
||||||
/* JPG + split JPG decoder library.
|
|
||||||
* Split JPG is a custom format optimized for embedded systems. */
|
|
||||||
#define LV_USE_SJPG 0
|
|
||||||
|
|
||||||
/*GIF decoder library*/
|
|
||||||
#define LV_USE_GIF 0
|
|
||||||
|
|
||||||
/*QR code library*/
|
|
||||||
#define LV_USE_QRCODE 0
|
|
||||||
|
|
||||||
/*FreeType library*/
|
|
||||||
#define LV_USE_FREETYPE 0
|
|
||||||
#if LV_USE_FREETYPE
|
|
||||||
/*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
|
|
||||||
#define LV_FREETYPE_CACHE_SIZE (16 * 1024)
|
|
||||||
#if LV_FREETYPE_CACHE_SIZE >= 0
|
|
||||||
/* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
|
|
||||||
/* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
|
|
||||||
/* if font size >= 256, must be configured as image cache */
|
|
||||||
#define LV_FREETYPE_SBIT_CACHE 0
|
|
||||||
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
|
|
||||||
/* (0:use system defaults) */
|
|
||||||
#define LV_FREETYPE_CACHE_FT_FACES 0
|
|
||||||
#define LV_FREETYPE_CACHE_FT_SIZES 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Rlottie library*/
|
|
||||||
#define LV_USE_RLOTTIE 0
|
|
||||||
|
|
||||||
/*FFmpeg library for image decoding and playing videos
|
|
||||||
*Supports all major image formats so do not enable other image decoder with it*/
|
|
||||||
#define LV_USE_FFMPEG 0
|
|
||||||
#if LV_USE_FFMPEG
|
|
||||||
/*Dump input information to stderr*/
|
|
||||||
#define LV_FFMPEG_DUMP_FORMAT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Others
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*1: Enable API to take snapshot for object*/
|
|
||||||
#define LV_USE_SNAPSHOT 0
|
|
||||||
|
|
||||||
/*1: Enable Monkey test*/
|
|
||||||
#define LV_USE_MONKEY 0
|
|
||||||
|
|
||||||
/*1: Enable grid navigation*/
|
|
||||||
#define LV_USE_GRIDNAV 0
|
|
||||||
|
|
||||||
/*1: Enable lv_obj fragment*/
|
|
||||||
#define LV_USE_FRAGMENT 0
|
|
||||||
|
|
||||||
/*1: Support using images as font in label or span widgets */
|
|
||||||
#define LV_USE_IMGFONT 0
|
|
||||||
|
|
||||||
/*1: Enable a published subscriber based messaging system */
|
|
||||||
#define LV_USE_MSG 0
|
|
||||||
|
|
||||||
/*1: Enable Pinyin input method*/
|
|
||||||
/*Requires: lv_keyboard*/
|
|
||||||
#define LV_USE_IME_PINYIN 0
|
|
||||||
#if LV_USE_IME_PINYIN
|
|
||||||
/*1: Use default thesaurus*/
|
|
||||||
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
|
|
||||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
|
|
||||||
/*Set the maximum number of candidate panels that can be displayed*/
|
|
||||||
/*This needs to be adjusted according to the size of the screen*/
|
|
||||||
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
|
|
||||||
|
|
||||||
/*Use 9 key input(k9)*/
|
|
||||||
#define LV_IME_PINYIN_USE_K9_MODE 1
|
|
||||||
#if LV_IME_PINYIN_USE_K9_MODE == 1
|
|
||||||
#define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
|
|
||||||
#endif // LV_IME_PINYIN_USE_K9_MODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* EXAMPLES
|
|
||||||
*==================*/
|
|
||||||
|
|
||||||
/*Enable the examples to be built with the library*/
|
|
||||||
#define LV_BUILD_EXAMPLES 1
|
|
||||||
|
|
||||||
/*===================
|
|
||||||
* DEMO USAGE
|
|
||||||
====================*/
|
|
||||||
|
|
||||||
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
|
|
||||||
#define LV_USE_DEMO_WIDGETS 1
|
|
||||||
#if LV_USE_DEMO_WIDGETS
|
|
||||||
#define LV_DEMO_WIDGETS_SLIDESHOW 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Demonstrate the usage of encoder and keyboard*/
|
|
||||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
|
||||||
|
|
||||||
/*Benchmark your system*/
|
|
||||||
#define LV_USE_DEMO_BENCHMARK 0
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
|
||||||
/*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/
|
|
||||||
#define LV_DEMO_BENCHMARK_RGB565A8 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Stress test for LVGL*/
|
|
||||||
#define LV_USE_DEMO_STRESS 0
|
|
||||||
|
|
||||||
/*Music player demo*/
|
|
||||||
#define LV_USE_DEMO_MUSIC 0
|
|
||||||
#if LV_USE_DEMO_MUSIC
|
|
||||||
#define LV_DEMO_MUSIC_SQUARE 0
|
|
||||||
#define LV_DEMO_MUSIC_LANDSCAPE 0
|
|
||||||
#define LV_DEMO_MUSIC_ROUND 0
|
|
||||||
#define LV_DEMO_MUSIC_LARGE 0
|
|
||||||
#define LV_DEMO_MUSIC_AUTO_PLAY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*--END OF LV_CONF_H--*/
|
|
||||||
|
|
||||||
#endif /*LV_CONF_H*/
|
|
||||||
|
|
||||||
#endif /*End of "Content enable"*/
|
|
@ -1 +0,0 @@
|
|||||||
#define LV_USE_DEMO_WIDGETS 1
|
|
@ -1,220 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_port_disp_templ.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_port_disp.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "main.h"
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#ifndef MY_DISP_HOR_RES
|
|
||||||
#define MY_DISP_HOR_RES LV_HOR_RES_MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MY_DISP_VER_RES
|
|
||||||
#define MY_DISP_VER_RES LV_VER_RES_MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void disp_init(void);
|
|
||||||
|
|
||||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
|
||||||
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
|
||||||
// const lv_area_t * fill_area, lv_color_t color);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static uint32_t lcdbuf_gui[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((section(".SDRAM")));
|
|
||||||
static uint32_t lcdbuf_show[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((section(".SDRAM")));
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_port_disp_init(void)
|
|
||||||
{
|
|
||||||
/*-------------------------
|
|
||||||
* Initialize your display
|
|
||||||
* -----------------------*/
|
|
||||||
disp_init();
|
|
||||||
|
|
||||||
/*-----------------------------
|
|
||||||
* Create a buffer for drawing
|
|
||||||
*----------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LVGL requires a buffer where it internally draws the widgets.
|
|
||||||
* Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
|
|
||||||
* The buffer has to be greater than 1 display row
|
|
||||||
*
|
|
||||||
* There are 3 buffering configurations:
|
|
||||||
* 1. Create ONE buffer:
|
|
||||||
* LVGL will draw the display's content here and writes it to your display
|
|
||||||
*
|
|
||||||
* 2. Create TWO buffer:
|
|
||||||
* LVGL will draw the display's content to a buffer and writes it your display.
|
|
||||||
* You should use DMA to write the buffer's content to the display.
|
|
||||||
* It will enable LVGL to draw the next part of the screen to the other buffer while
|
|
||||||
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
|
|
||||||
*
|
|
||||||
* 3. Double buffering
|
|
||||||
* Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
|
|
||||||
* This way LVGL will always provide the whole rendered screen in `flush_cb`
|
|
||||||
* and you only need to change the frame buffer's address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Example for 2) */
|
|
||||||
static lv_disp_draw_buf_t draw_buf_dsc;
|
|
||||||
static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
|
|
||||||
static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/
|
|
||||||
lv_disp_draw_buf_init(&draw_buf_dsc, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
|
|
||||||
|
|
||||||
/*-----------------------------------
|
|
||||||
* Register the display in LVGL
|
|
||||||
*----------------------------------*/
|
|
||||||
|
|
||||||
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
|
||||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
|
||||||
|
|
||||||
/*Set up the functions to access to your display*/
|
|
||||||
|
|
||||||
/*Set the resolution of the display*/
|
|
||||||
disp_drv.hor_res = MY_DISP_HOR_RES;
|
|
||||||
disp_drv.ver_res = MY_DISP_VER_RES;
|
|
||||||
|
|
||||||
/*Used to copy the buffer's content to the display*/
|
|
||||||
disp_drv.flush_cb = disp_flush;
|
|
||||||
|
|
||||||
/*Set a display buffer*/
|
|
||||||
disp_drv.draw_buf = &draw_buf_dsc;
|
|
||||||
|
|
||||||
/*Required for Example 3)*/
|
|
||||||
//disp_drv.full_refresh = 1;
|
|
||||||
|
|
||||||
/* Fill a memory array with a color if you have GPU.
|
|
||||||
* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
|
|
||||||
* But if you have a different GPU you can use with this callback.*/
|
|
||||||
//disp_drv.gpu_fill_cb = gpu_fill;
|
|
||||||
|
|
||||||
/*Finally register the driver*/
|
|
||||||
lv_disp_drv_register(&disp_drv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*Initialize your display and the required peripherals.*/
|
|
||||||
static void disp_init(void)
|
|
||||||
{
|
|
||||||
/*You code here*/
|
|
||||||
lcd_rgb_init();
|
|
||||||
LCD->SRCADDR = (uint32_t)lcdbuf_show;
|
|
||||||
LCD_Start(LCD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void drawpoint(int16_t x, int16_t y, uint32_t c)
|
|
||||||
{
|
|
||||||
uint32_t temp;
|
|
||||||
uint32_t index = ((LV_HOR_RES -1- x)*LV_VER_RES+y)/2;
|
|
||||||
uint32_t pos = ((y%2) == 0 ? 0 : 16);
|
|
||||||
temp = lcdbuf_gui[index];
|
|
||||||
temp &= ~(0xFFFF << pos);
|
|
||||||
temp |= (c << pos);
|
|
||||||
lcdbuf_gui[index] = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui2show(void)
|
|
||||||
{
|
|
||||||
// uint32_t index;
|
|
||||||
// for(uint32_t i = 0; i < LV_VER_RES; i++)
|
|
||||||
// {
|
|
||||||
// for(uint32_t j = 0; j < LV_HOR_RES / 2; j++)
|
|
||||||
// {
|
|
||||||
// index = i * LV_HOR_RES / 2 + j;
|
|
||||||
// lcdbuf_show[index] = lcdbuf_gui[index];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
memcpy(lcdbuf_show,lcdbuf_gui,sizeof(lcdbuf_show));
|
|
||||||
}
|
|
||||||
|
|
||||||
volatile bool disp_flush_enabled = true;
|
|
||||||
|
|
||||||
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
|
||||||
*/
|
|
||||||
void disp_enable_update(void)
|
|
||||||
{
|
|
||||||
disp_flush_enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
|
||||||
*/
|
|
||||||
void disp_disable_update(void)
|
|
||||||
{
|
|
||||||
disp_flush_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Flush the content of the internal buffer the specific area on the display
|
|
||||||
*You can use DMA or any hardware acceleration to do this operation in the background but
|
|
||||||
*'lv_disp_flush_ready()' has to be called when finished.*/
|
|
||||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
|
||||||
{
|
|
||||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
|
||||||
|
|
||||||
int32_t x;
|
|
||||||
int32_t y;
|
|
||||||
for(y = area->y1; y <= area->y2; y++) {
|
|
||||||
for(x = area->x1; x <= area->x2; x++) {
|
|
||||||
/* Put a pixel to the display. For example: */
|
|
||||||
/* put_px(x, y, *color_p)*/
|
|
||||||
drawpoint(x, y, color_p->full);
|
|
||||||
color_p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* IMPORTANT!!!
|
|
||||||
* Inform the graphics library that you are ready with the flushing*/
|
|
||||||
lv_disp_flush_ready(disp_drv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*OPTIONAL: GPU INTERFACE*/
|
|
||||||
|
|
||||||
/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
|
|
||||||
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
|
||||||
// const lv_area_t * fill_area, lv_color_t color)
|
|
||||||
//{
|
|
||||||
// /*It's an example code which should be done by your GPU*/
|
|
||||||
// int32_t x, y;
|
|
||||||
// dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
|
|
||||||
//
|
|
||||||
// for(y = fill_area->y1; y <= fill_area->y2; y++) {
|
|
||||||
// for(x = fill_area->x1; x <= fill_area->x2; x++) {
|
|
||||||
// dest_buf[x] = color;
|
|
||||||
// }
|
|
||||||
// dest_buf+=dest_width; /*Go to the next line*/
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
#else /*Enable this file at the top*/
|
|
||||||
|
|
||||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
|
||||||
typedef int keep_pedantic_happy;
|
|
||||||
#endif
|
|
@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_port_disp_templ.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
#ifndef LV_PORT_DISP_TEMPL_H
|
|
||||||
#define LV_PORT_DISP_TEMPL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
|
||||||
#include "lvgl.h"
|
|
||||||
#else
|
|
||||||
#include "lvgl/lvgl.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
/* Initialize low level display driver */
|
|
||||||
void lv_port_disp_init(void);
|
|
||||||
void gui2show(void);
|
|
||||||
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
|
||||||
*/
|
|
||||||
void disp_enable_update(void);
|
|
||||||
|
|
||||||
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
|
||||||
*/
|
|
||||||
void disp_disable_update(void);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_PORT_DISP_TEMPL_H*/
|
|
||||||
|
|
||||||
#endif /*Disable/Enable content*/
|
|
@ -1,266 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_port_fs_templ.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_port_fs.h"
|
|
||||||
#include "lvgl.h"
|
|
||||||
#include "ff.h"
|
|
||||||
#include "main.h"
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/* Create a type to store the required data about your file.*/
|
|
||||||
typedef FIL file_t;
|
|
||||||
|
|
||||||
/*Similarly to `file_t` create a type for directory reading too */
|
|
||||||
typedef DIR dir_t;
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void fs_init(void);
|
|
||||||
|
|
||||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
|
|
||||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
|
|
||||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
|
||||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
|
||||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
|
|
||||||
static lv_fs_res_t fs_size(lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);
|
|
||||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
|
|
||||||
|
|
||||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path);
|
|
||||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn);
|
|
||||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
#define lv_debug(...) printf(__VA_ARGS__)
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_port_fs_init(void)
|
|
||||||
{
|
|
||||||
/*----------------------------------------------------
|
|
||||||
* Initialize your storage device and File System
|
|
||||||
* -------------------------------------------------*/
|
|
||||||
fs_init();
|
|
||||||
|
|
||||||
/*---------------------------------------------------
|
|
||||||
* Register the file system interface in LVGL
|
|
||||||
*--------------------------------------------------*/
|
|
||||||
|
|
||||||
/*Add a simple drive to open images*/
|
|
||||||
static lv_fs_drv_t fs_drv;
|
|
||||||
lv_fs_drv_init(&fs_drv);
|
|
||||||
|
|
||||||
/*Set up fields...*/
|
|
||||||
fs_drv.letter = 'P';
|
|
||||||
fs_drv.open_cb = fs_open;
|
|
||||||
fs_drv.close_cb = fs_close;
|
|
||||||
fs_drv.read_cb = fs_read;
|
|
||||||
fs_drv.write_cb = fs_write;
|
|
||||||
fs_drv.seek_cb = fs_seek;
|
|
||||||
fs_drv.tell_cb = fs_tell;
|
|
||||||
|
|
||||||
fs_drv.dir_close_cb = fs_dir_close;
|
|
||||||
fs_drv.dir_open_cb = fs_dir_open;
|
|
||||||
fs_drv.dir_read_cb = fs_dir_read;
|
|
||||||
|
|
||||||
lv_fs_drv_register(&fs_drv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*Initialize your Storage device and File system.*/
|
|
||||||
static void fs_init(void)
|
|
||||||
{
|
|
||||||
/*E.g. for FatFS initialize the SD card and FatFS itself*/
|
|
||||||
|
|
||||||
/*You code here*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a file
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
|
|
||||||
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
|
|
||||||
* @return a file descriptor or NULL on error
|
|
||||||
*/
|
|
||||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
|
|
||||||
{
|
|
||||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
|
||||||
uint8_t flags = 0;
|
|
||||||
void * f = NULL;
|
|
||||||
|
|
||||||
if(mode == LV_FS_MODE_WR) {
|
|
||||||
/*Open a file for write*/
|
|
||||||
flags = FA_WRITE | FA_OPEN_ALWAYS;
|
|
||||||
}
|
|
||||||
else if(mode == LV_FS_MODE_RD) {
|
|
||||||
/*Open a file for read*/
|
|
||||||
flags = FA_READ;
|
|
||||||
}
|
|
||||||
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) {
|
|
||||||
/*Open a file for read and write*/
|
|
||||||
flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS;
|
|
||||||
}
|
|
||||||
f_open(f, path, flags);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close an opened file
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param file_p pointer to a file_t variable. (opened with fs_open)
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
|
|
||||||
{
|
|
||||||
f_close(file_p);
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read data from an opened file
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param file_p pointer to a file_t variable.
|
|
||||||
* @param buf pointer to a memory block where to store the read data
|
|
||||||
* @param btr number of Bytes To Read
|
|
||||||
* @param br the real number of read bytes (Byte Read)
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
|
|
||||||
{
|
|
||||||
FRESULT res = f_read(file_p, buf, btr, (UINT *)br);
|
|
||||||
if(res == FR_OK)
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
else
|
|
||||||
return LV_FS_RES_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write into a file
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param file_p pointer to a file_t variable
|
|
||||||
* @param buf pointer to a buffer with the bytes to write
|
|
||||||
* @param btw Bytes To Write
|
|
||||||
* @param bw the number of real written bytes (Bytes Written). NULL if unused.
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
|
|
||||||
{
|
|
||||||
FRESULT res = f_write(file_p, buf, btw, (UINT *)bw);
|
|
||||||
if(res == FR_OK)
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
else
|
|
||||||
return LV_FS_RES_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the read write pointer. Also expand the file size if necessary.
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param file_p pointer to a file_t variable. (opened with fs_open )
|
|
||||||
* @param pos the new position of read write pointer
|
|
||||||
* @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
|
|
||||||
{
|
|
||||||
f_lseek(file_p, pos);
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Give the position of the read write pointer
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param file_p pointer to a file_t variable.
|
|
||||||
* @param pos_p pointer to to store the result
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
|
||||||
{
|
|
||||||
*pos_p = f_tell(((file_t *)file_p));
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a 'lv_fs_dir_t' variable for directory reading
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param path path to a directory
|
|
||||||
* @return pointer to the directory read descriptor or NULL on error
|
|
||||||
*/
|
|
||||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
|
|
||||||
{
|
|
||||||
void * rddir_p = NULL;
|
|
||||||
f_opendir(rddir_p, path);
|
|
||||||
return rddir_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the next filename form a directory.
|
|
||||||
* The name of the directories will begin with '/'
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
|
|
||||||
* @param fn pointer to a buffer to store the filename
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
FILINFO fno;
|
|
||||||
fn[0] = '\0';
|
|
||||||
|
|
||||||
do {
|
|
||||||
res = f_readdir(rddir_p, &fno);
|
|
||||||
if(res != FR_OK) return LV_FS_RES_UNKNOWN;
|
|
||||||
|
|
||||||
if(fno.fattrib & AM_DIR) {
|
|
||||||
fn[0] = '/';
|
|
||||||
strcpy(&fn[1], fno.fname);
|
|
||||||
} else
|
|
||||||
strcpy(fn, fno.fname);
|
|
||||||
|
|
||||||
} while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
|
|
||||||
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the directory reading
|
|
||||||
* @param drv pointer to a driver where this function belongs
|
|
||||||
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
|
|
||||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
|
||||||
*/
|
|
||||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p)
|
|
||||||
{
|
|
||||||
f_closedir(rddir_p);
|
|
||||||
return LV_FS_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /*Enable this file at the top*/
|
|
||||||
|
|
||||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
|
||||||
typedef int keep_pedantic_happy;
|
|
||||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_port_fs_templ.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_fs.h" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
#ifndef LV_PORT_FS_TEMPL_H
|
|
||||||
#define LV_PORT_FS_TEMPL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lvgl/lvgl.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
void lv_port_fs_init(void);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_PORT_FS_TEMPL_H*/
|
|
||||||
|
|
||||||
#endif /*Disable/Enable content*/
|
|
@ -1,423 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_port_indev_templ.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_port_indev.h"
|
|
||||||
#include "lvgl.h"
|
|
||||||
#include "main.h"
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void touchpad_init(void);
|
|
||||||
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
|
||||||
static bool touchpad_is_pressed(void);
|
|
||||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
|
|
||||||
|
|
||||||
static void mouse_init(void);
|
|
||||||
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
|
||||||
static bool mouse_is_pressed(void);
|
|
||||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
|
|
||||||
|
|
||||||
static void keypad_init(void);
|
|
||||||
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
|
||||||
static uint32_t keypad_get_key(void);
|
|
||||||
|
|
||||||
static void encoder_init(void);
|
|
||||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
|
||||||
static void encoder_handler(void);
|
|
||||||
|
|
||||||
static void button_init(void);
|
|
||||||
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
|
||||||
static int8_t button_get_pressed_id(void);
|
|
||||||
static bool button_is_pressed(uint8_t id);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
lv_indev_t * indev_touchpad;
|
|
||||||
lv_indev_t * indev_mouse;
|
|
||||||
lv_indev_t * indev_keypad;
|
|
||||||
lv_indev_t * indev_encoder;
|
|
||||||
lv_indev_t * indev_button;
|
|
||||||
|
|
||||||
static int32_t encoder_diff;
|
|
||||||
static lv_indev_state_t encoder_state;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_port_indev_init(void)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Here you will find example implementation of input devices supported by LittelvGL:
|
|
||||||
* - Touchpad
|
|
||||||
* - Mouse (with cursor support)
|
|
||||||
* - Keypad (supports GUI usage only with key)
|
|
||||||
* - Encoder (supports GUI usage only with: left, right, push)
|
|
||||||
* - Button (external buttons to press points on the screen)
|
|
||||||
*
|
|
||||||
* The `..._read()` function are only examples.
|
|
||||||
* You should shape them according to your hardware
|
|
||||||
*/
|
|
||||||
|
|
||||||
static lv_indev_drv_t indev_drv;
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Touchpad
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your touchpad if you have*/
|
|
||||||
touchpad_init();
|
|
||||||
|
|
||||||
/*Register a touchpad input device*/
|
|
||||||
lv_indev_drv_init(&indev_drv);
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
|
||||||
indev_drv.read_cb = touchpad_read;
|
|
||||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Mouse
|
|
||||||
* -----------------*/
|
|
||||||
#if 0
|
|
||||||
/*Initialize your mouse if you have*/
|
|
||||||
mouse_init();
|
|
||||||
|
|
||||||
/*Register a mouse input device*/
|
|
||||||
lv_indev_drv_init(&indev_drv);
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
|
||||||
indev_drv.read_cb = mouse_read;
|
|
||||||
indev_mouse = lv_indev_drv_register(&indev_drv);
|
|
||||||
|
|
||||||
/*Set cursor. For simplicity set a HOME symbol now.*/
|
|
||||||
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
|
|
||||||
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
|
|
||||||
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
|
||||||
/*------------------
|
|
||||||
* Keypad
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your keypad or keyboard if you have*/
|
|
||||||
keypad_init();
|
|
||||||
|
|
||||||
/*Register a keypad input device*/
|
|
||||||
lv_indev_drv_init(&indev_drv);
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
|
||||||
indev_drv.read_cb = keypad_read;
|
|
||||||
indev_keypad = lv_indev_drv_register(&indev_drv);
|
|
||||||
|
|
||||||
/*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
|
||||||
*add objects to the group with `lv_group_add_obj(group, obj)`
|
|
||||||
*and assign this input device to group to navigate in it:
|
|
||||||
*`lv_indev_set_group(indev_keypad, group);`*/
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Encoder
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your encoder if you have*/
|
|
||||||
encoder_init();
|
|
||||||
|
|
||||||
/*Register a encoder input device*/
|
|
||||||
lv_indev_drv_init(&indev_drv);
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_ENCODER;
|
|
||||||
indev_drv.read_cb = encoder_read;
|
|
||||||
indev_encoder = lv_indev_drv_register(&indev_drv);
|
|
||||||
|
|
||||||
/*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
|
||||||
*add objects to the group with `lv_group_add_obj(group, obj)`
|
|
||||||
*and assign this input device to group to navigate in it:
|
|
||||||
*`lv_indev_set_group(indev_encoder, group);`*/
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Button
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your button if you have*/
|
|
||||||
button_init();
|
|
||||||
|
|
||||||
/*Register a button input device*/
|
|
||||||
lv_indev_drv_init(&indev_drv);
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_BUTTON;
|
|
||||||
indev_drv.read_cb = button_read;
|
|
||||||
indev_button = lv_indev_drv_register(&indev_drv);
|
|
||||||
|
|
||||||
/*Assign buttons to points on the screen*/
|
|
||||||
static const lv_point_t btn_points[2] = {
|
|
||||||
{10, 10}, /*Button 0 -> x:10; y:10*/
|
|
||||||
{40, 100}, /*Button 1 -> x:40; y:100*/
|
|
||||||
};
|
|
||||||
lv_indev_set_button_points(indev_button, btn_points);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Touchpad
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your touchpad*/
|
|
||||||
static void touchpad_init(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
// gt9147_init();
|
|
||||||
GT911_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Will be called by the library to read the touchpad*/
|
|
||||||
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
|
||||||
{
|
|
||||||
static lv_coord_t last_x = 0;
|
|
||||||
static lv_coord_t last_y = 0;
|
|
||||||
|
|
||||||
/*Save the pressed coordinates and the state*/
|
|
||||||
if (touchpad_is_pressed())
|
|
||||||
{
|
|
||||||
touchpad_get_xy(&last_x, &last_y);
|
|
||||||
data->state = LV_INDEV_STATE_PR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data->state = LV_INDEV_STATE_REL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Set the last pressed coordinates*/
|
|
||||||
data->point.x = last_x;
|
|
||||||
data->point.y = last_y;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Return true is the touchpad is pressed*/
|
|
||||||
static bool touchpad_is_pressed(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
if(tp_dev.sta & 0x80)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Get the x and y coordinates if the touchpad is pressed*/
|
|
||||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
(*x) = tp_dev.x[0];
|
|
||||||
(*y) = tp_dev.y[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Mouse
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your mouse*/
|
|
||||||
static void mouse_init(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Will be called by the library to read the mouse*/
|
|
||||||
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
|
||||||
{
|
|
||||||
/*Get the current x and y coordinates*/
|
|
||||||
mouse_get_xy(&data->point.x, &data->point.y);
|
|
||||||
|
|
||||||
/*Get whether the mouse button is pressed or released*/
|
|
||||||
if(mouse_is_pressed()) {
|
|
||||||
data->state = LV_INDEV_STATE_PR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data->state = LV_INDEV_STATE_REL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Return true is the mouse button is pressed*/
|
|
||||||
static bool mouse_is_pressed(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Get the x and y coordinates if the mouse is pressed*/
|
|
||||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
(*x) = 0;
|
|
||||||
(*y) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Keypad
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your keypad*/
|
|
||||||
static void keypad_init(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Will be called by the library to read the mouse*/
|
|
||||||
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
|
||||||
{
|
|
||||||
static uint32_t last_key = 0;
|
|
||||||
|
|
||||||
/*Get the current x and y coordinates*/
|
|
||||||
mouse_get_xy(&data->point.x, &data->point.y);
|
|
||||||
|
|
||||||
/*Get whether the a key is pressed and save the pressed key*/
|
|
||||||
uint32_t act_key = keypad_get_key();
|
|
||||||
if(act_key != 0) {
|
|
||||||
data->state = LV_INDEV_STATE_PR;
|
|
||||||
|
|
||||||
/*Translate the keys to LVGL control characters according to your key definitions*/
|
|
||||||
switch(act_key) {
|
|
||||||
case 1:
|
|
||||||
act_key = LV_KEY_NEXT;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
act_key = LV_KEY_PREV;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
act_key = LV_KEY_LEFT;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
act_key = LV_KEY_RIGHT;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
act_key = LV_KEY_ENTER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_key = act_key;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data->state = LV_INDEV_STATE_REL;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->key = last_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Get the currently being pressed key. 0 if no key is pressed*/
|
|
||||||
static uint32_t keypad_get_key(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Encoder
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your keypad*/
|
|
||||||
static void encoder_init(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Will be called by the library to read the encoder*/
|
|
||||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
|
||||||
{
|
|
||||||
|
|
||||||
data->enc_diff = encoder_diff;
|
|
||||||
data->state = encoder_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Call this function in an interrupt to process encoder events (turn, press)*/
|
|
||||||
static void encoder_handler(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
encoder_diff += 0;
|
|
||||||
encoder_state = LV_INDEV_STATE_REL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------
|
|
||||||
* Button
|
|
||||||
* -----------------*/
|
|
||||||
|
|
||||||
/*Initialize your buttons*/
|
|
||||||
static void button_init(void)
|
|
||||||
{
|
|
||||||
/*Your code comes here*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Will be called by the library to read the button*/
|
|
||||||
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
|
||||||
{
|
|
||||||
|
|
||||||
static uint8_t last_btn = 0;
|
|
||||||
|
|
||||||
/*Get the pressed button's ID*/
|
|
||||||
int8_t btn_act = button_get_pressed_id();
|
|
||||||
|
|
||||||
if(btn_act >= 0) {
|
|
||||||
data->state = LV_INDEV_STATE_PR;
|
|
||||||
last_btn = btn_act;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data->state = LV_INDEV_STATE_REL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Save the last pressed button's ID*/
|
|
||||||
data->btn_id = last_btn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Get ID (0, 1, 2 ..) of the pressed button*/
|
|
||||||
static int8_t button_get_pressed_id(void)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
/*Check to buttons see which is being pressed (assume there are 2 buttons)*/
|
|
||||||
for(i = 0; i < 2; i++) {
|
|
||||||
/*Return the pressed button's ID*/
|
|
||||||
if(button_is_pressed(i)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*No button pressed*/
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Test if `id` button is pressed or not*/
|
|
||||||
static bool button_is_pressed(uint8_t id)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*Your code comes here*/
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /*Enable this file at the top*/
|
|
||||||
|
|
||||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
|
||||||
typedef int keep_pedantic_happy;
|
|
||||||
#endif
|
|
@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* @file lv_port_indev_templ.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*Copy this file as "lv_port_indev.h" and set this value to "1" to enable content*/
|
|
||||||
#if 1
|
|
||||||
|
|
||||||
#ifndef LV_PORT_INDEV_TEMPL_H
|
|
||||||
#define LV_PORT_INDEV_TEMPL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lvgl/lvgl.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
void lv_port_indev_init(void);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_PORT_INDEV_TEMPL_H*/
|
|
||||||
|
|
||||||
#endif /*Disable/Enable content*/
|
|
@ -1,8 +0,0 @@
|
|||||||
codecov:
|
|
||||||
notify:
|
|
||||||
require_ci_to_pass: true
|
|
||||||
comment: off
|
|
||||||
coverage:
|
|
||||||
status:
|
|
||||||
patch: off
|
|
||||||
project: off
|
|
@ -1,6 +0,0 @@
|
|||||||
[*.{c,h,ino}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
1
bsp/swm320/APP/lvgl/.github/FUNDING.yml
vendored
1
bsp/swm320/APP/lvgl/.github/FUNDING.yml
vendored
@ -1 +0,0 @@
|
|||||||
open_collective: lvgl
|
|
@ -1,44 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a bug report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
IMPORTANT
|
|
||||||
Issues that don't use this template will be ignored and closed.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Perform all steps below and tick them with [x]
|
|
||||||
- [ ] Read the [FAQ](https://docs.lvgl.io/master/intro/index.html#faq)
|
|
||||||
- [ ] Check the related part of the [Documentation](https://docs.lvgl.io/)
|
|
||||||
- [ ] Update lvgl to the latest version
|
|
||||||
- [ ] Reproduce the issue in a [Simulator](https://docs.lvgl.io/latest/en/html/get-started/pc-simulator.html)
|
|
||||||
|
|
||||||
### Describe the bug
|
|
||||||
<!--
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### To Reproduce
|
|
||||||
<!--
|
|
||||||
Provide a small, independent code sample that can be used to reproduce the issue.
|
|
||||||
Ideally this should work in the PC simulator unless the problem is specific to a platform.
|
|
||||||
Format the code like this:
|
|
||||||
```c
|
|
||||||
your code here
|
|
||||||
```
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Expected behavior
|
|
||||||
<!--
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Screenshots or video
|
|
||||||
<!--
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
-->
|
|
@ -1,14 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: Documentation
|
|
||||||
url: https://docs.lvgl.io
|
|
||||||
about: Be sure to read to documentation first
|
|
||||||
- name: Forum
|
|
||||||
url: https://forum.lvgl.io
|
|
||||||
about: For topics like How-to, Getting started, Feature request
|
|
||||||
- name: CONTIBUTING.md
|
|
||||||
url: https://github.com/lvgl/lvgl/blob/master/docs/CONTRIBUTING.md#faq-about-contributing
|
|
||||||
about: The basic rules of contributing
|
|
||||||
- name: CODING_STYLE.md
|
|
||||||
url: https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md
|
|
||||||
about: Quick summary of LVGL's code style
|
|
@ -1,29 +0,0 @@
|
|||||||
---
|
|
||||||
name: Development discussion
|
|
||||||
about: Discussion strictly related to the development of the LVGL.
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
<!--
|
|
||||||
IMPORTANT
|
|
||||||
Issues that don't use this template will be ignored and closed.
|
|
||||||
|
|
||||||
Normal Feature requests should go to the Forum: https://forum.lvgl.io/c/feature-request/9
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Introduce the problem
|
|
||||||
<!--
|
|
||||||
A clear and concise description of the problem.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Examples and cases
|
|
||||||
<!--
|
|
||||||
Mention some examples and cases where the problem or the missing feature is relevant
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Suggested solution
|
|
||||||
<!--
|
|
||||||
If you already have an idea about the solution share it here
|
|
||||||
-->
|
|
12
bsp/swm320/APP/lvgl/.github/auto-comment.yml
vendored
12
bsp/swm320/APP/lvgl/.github/auto-comment.yml
vendored
@ -1,12 +0,0 @@
|
|||||||
# Comment to a new issue.
|
|
||||||
pullRequestOpened: |
|
|
||||||
Thank you for raising your pull request.
|
|
||||||
|
|
||||||
To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin).
|
|
||||||
|
|
||||||
The text of DCO can be read here: https://developercertificate.org/
|
|
||||||
For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site.
|
|
||||||
|
|
||||||
By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO.
|
|
||||||
|
|
||||||
No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment.
|
|
@ -1,8 +0,0 @@
|
|||||||
### Description of the feature or fix
|
|
||||||
|
|
||||||
A clear and concise description of what the bug or new feature is.
|
|
||||||
|
|
||||||
### Checkpoints
|
|
||||||
- [ ] Follow the [styling guide](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md)
|
|
||||||
- [ ] Run `code-format.py` from the `scripts` folder. [astyle](http://astyle.sourceforge.net/install.html) needs to be installed.
|
|
||||||
- [ ] Update the documentation
|
|
@ -1,15 +0,0 @@
|
|||||||
name: Arduino Lint
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: arduino/arduino-lint-action@v1
|
|
||||||
with:
|
|
||||||
library-manager: update
|
|
@ -1,74 +0,0 @@
|
|||||||
name: Micropython CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
name: Build ${{ matrix.port }} port
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
continue-on-error: true
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
port: ['unix', 'esp32', 'stm32', 'rp2']
|
|
||||||
steps:
|
|
||||||
- uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: |
|
|
||||||
sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
|
||||||
sudo apt-get update -y -qq
|
|
||||||
sudo apt-get install libsdl2-dev parallel libfreetype-dev librlottie-dev
|
|
||||||
- name: Clone lv_micropython
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/lvgl/lv_micropython.git .
|
|
||||||
git checkout master
|
|
||||||
- name: Initialize lv_bindings submodule
|
|
||||||
run: git submodule update --init --recursive lib/lv_bindings
|
|
||||||
- name: Update ${{ matrix.port }} port submodules
|
|
||||||
if: matrix.port != 'esp32'
|
|
||||||
# VARIANT needed for unix
|
|
||||||
run: make -C ports/${{ matrix.port }} VARIANT=dev DEBUG=1 USER_C_MODULES=../../lib/lv_bindings/bindings.cmake submodules
|
|
||||||
- name: Checkout LVGL submodule
|
|
||||||
working-directory: ./lib/lv_bindings/lvgl
|
|
||||||
run: |
|
|
||||||
git fetch --force ${{ github.event.repository.html_url }} "+refs/heads/*:refs/remotes/origin/*"
|
|
||||||
git fetch --force ${{ github.event.repository.html_url }} "+refs/pull/*:refs/remotes/origin/pr/*"
|
|
||||||
git checkout ${{ github.sha }} || git checkout ${{ github.event.pull_request.head.sha }}
|
|
||||||
git submodule update --init --recursive
|
|
||||||
- name: Build mpy-cross
|
|
||||||
run: make -j $(nproc) -C mpy-cross
|
|
||||||
|
|
||||||
# ESP32 port
|
|
||||||
- name: Setup ESP-IDF
|
|
||||||
if: matrix.port == 'esp32'
|
|
||||||
run: |
|
|
||||||
source tools/ci.sh && ci_esp32_idf44_setup
|
|
||||||
- name: Build ESP32 port
|
|
||||||
if: matrix.port == 'esp32'
|
|
||||||
run: |
|
|
||||||
source tools/ci.sh && ci_esp32_build
|
|
||||||
|
|
||||||
# STM32 & RPi Pico port
|
|
||||||
- name: arm-none-eabi-gcc
|
|
||||||
if: matrix.port == 'stm32' || matrix.port == 'rp2'
|
|
||||||
uses: carlosperate/arm-none-eabi-gcc-action@v1.3.0
|
|
||||||
with:
|
|
||||||
release: '9-2019-q4' # The arm-none-eabi-gcc release to use.
|
|
||||||
- name: Build STM32 port
|
|
||||||
if: matrix.port == 'stm32'
|
|
||||||
run: make -j $(nproc) -C ports/stm32 BOARD=STM32F7DISC
|
|
||||||
- name: Build Raspberry Pi PICO port
|
|
||||||
if: matrix.port == 'rp2'
|
|
||||||
run: make -j $(nproc) -C ports/rp2 BOARD=PICO USER_C_MODULES=../../lib/lv_bindings/bindings.cmake
|
|
||||||
# Unix port
|
|
||||||
- name: Build Unix port
|
|
||||||
if: matrix.port == 'unix'
|
|
||||||
run: make -j $(nproc) -C ports/unix VARIANT=dev DEBUG=1
|
|
||||||
- name: Run tests
|
|
||||||
if: success() && matrix.port == 'unix'
|
|
||||||
run: |
|
|
||||||
export XDG_RUNTIME_DIR=/tmp
|
|
||||||
lib/lv_bindings/tests/run.sh
|
|
||||||
|
|
96
bsp/swm320/APP/lvgl/.github/workflows/ccpp.yml
vendored
96
bsp/swm320/APP/lvgl/.github/workflows/ccpp.yml
vendored
@ -1,96 +0,0 @@
|
|||||||
name: C/C++ CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# A valid option parameter to the cmake file.
|
|
||||||
# See BUILD_OPTIONS in tests/CMakeLists.txt.
|
|
||||||
build_option: ['OPTIONS_MINIMAL_MONOCHROME',
|
|
||||||
'OPTIONS_NORMAL_8BIT',
|
|
||||||
'OPTIONS_16BIT',
|
|
||||||
'OPTIONS_16BIT_SWAP',
|
|
||||||
'OPTIONS_FULL_32BIT']
|
|
||||||
name: Build ${{ matrix.build_option }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
- name: Install prerequisites
|
|
||||||
run: scripts/install-prerequisites.sh
|
|
||||||
- name: Building ${{ matrix.build_option }}
|
|
||||||
run: python tests/main.py --build-option=${{ matrix.build_option }} build
|
|
||||||
|
|
||||||
test-native:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: amd64 Executable Tests
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
- name: Install prerequisites
|
|
||||||
run: scripts/install-prerequisites.sh
|
|
||||||
- name: Run tests
|
|
||||||
run: python tests/main.py --report test
|
|
||||||
- name: Upload coverage to Codecov
|
|
||||||
uses: codecov/codecov-action@v2
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: true
|
|
||||||
verbose: true
|
|
||||||
test-cross:
|
|
||||||
# The host should always be linux
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: ${{ matrix.arch }} Executable Tests
|
|
||||||
|
|
||||||
# Run steps on a matrix of 3 arch/distro combinations
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: [ 'aarch64', 'armv6', 'armv7' ]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2.1.0
|
|
||||||
- uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
- name: Setup cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.ccache
|
|
||||||
key: lvgl_ci_cross_test_ccache_${{ matrix.arch }}_${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
lvgl_ci_cross_test_ccache_${{ matrix.arch }}
|
|
||||||
- uses: uraimo/run-on-arch-action@v2.1.1
|
|
||||||
name: Run tests
|
|
||||||
id: build
|
|
||||||
with:
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
distro: bullseye
|
|
||||||
|
|
||||||
# Not required, but speeds up builds
|
|
||||||
githubToken: ${{ github.token }}
|
|
||||||
|
|
||||||
# The shell to run commands with in the container
|
|
||||||
shell: /bin/bash
|
|
||||||
|
|
||||||
# Create cached/volume directories on host
|
|
||||||
setup: |
|
|
||||||
mkdir -p ~/.ccache
|
|
||||||
|
|
||||||
# Mount cached directories in the container for faster builds
|
|
||||||
dockerRunArgs: |
|
|
||||||
--volume "${HOME}/.ccache:/root/.ccache"
|
|
||||||
|
|
||||||
install: |
|
|
||||||
apt-get update -y
|
|
||||||
apt-get install build-essential ccache python3 libpng-dev ruby-full gcovr cmake -q -y
|
|
||||||
/usr/sbin/update-ccache-symlinks
|
|
||||||
echo 'export PATH="/usr/lib/ccache:$PATH"' | tee -a ~/.bashrc
|
|
||||||
|
|
||||||
run: |
|
|
||||||
env PATH="/usr/lib/ccache:$PATH" ASAN_OPTIONS=detect_leaks=0 python3 tests/main.py test
|
|
@ -1,24 +0,0 @@
|
|||||||
name: Verify that lv_conf_internal.h matches repository state
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
verify-conf-internal:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup Python
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Generate lv_conf_internal.h
|
|
||||||
run: python lv_conf_internal_gen.py
|
|
||||||
working-directory: scripts
|
|
||||||
- name: Check that repository is clean
|
|
||||||
run: git diff --exit-code >/dev/null 2>&1 || (echo "Please regenerate lv_conf_internal.h using scripts/lv_conf_internal_gen.py"; false)
|
|
@ -1,31 +0,0 @@
|
|||||||
name: Verify code formatting
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
verify-formatting:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Install astyle
|
|
||||||
run: |
|
|
||||||
sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
|
||||||
sudo apt-get update -y -qq
|
|
||||||
sudo apt-get install astyle
|
|
||||||
- name: Format code
|
|
||||||
run: python code-format.py
|
|
||||||
working-directory: scripts
|
|
||||||
- name: Check that repository is clean
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -o pipefail
|
|
||||||
if ! (git diff --exit-code --color=always | tee /tmp/lvgl_diff.patch); then
|
|
||||||
echo "Please apply the preceding diff to your code or run scripts/code-format.py"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
@ -1,29 +0,0 @@
|
|||||||
name: 'Close stale issues and PRs'
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '30 1 * * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
if: github.repository == 'lvgl/lvgl'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v5
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.LVGL_BOT_TOKEN }}
|
|
||||||
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
|
||||||
stale-pr-message: |
|
|
||||||
We need some feedback on this issue.
|
|
||||||
|
|
||||||
Now we mark this as "stale" because there was no activity here for 14 days.
|
|
||||||
|
|
||||||
Remove the "stale" label or comment else this will be closed in 7 days.
|
|
||||||
close-issue-message: |
|
|
||||||
As there was no activity here for a while we close this issue. But don't worry, the conversation is still here and you can get back to it at any time.
|
|
||||||
|
|
||||||
So feel free to comment if you have remarks or ideas on this topic.
|
|
||||||
days-before-stale: 14
|
|
||||||
days-before-close: 7
|
|
||||||
exempt-issue-labels: 'pinned'
|
|
||||||
exempt-pr-labels: 'pinned'
|
|
@ -1,93 +0,0 @@
|
|||||||
name: Build docs
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- 'release/*'
|
|
||||||
env:
|
|
||||||
EM_VERSION: 2.0.4
|
|
||||||
EM_CACHE_FOLDER: 'emsdk-cache'
|
|
||||||
jobs:
|
|
||||||
build-and-deploy:
|
|
||||||
if: github.repository == 'lvgl/lvgl'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
concurrency: docs-build-and-deploy
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup Python
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Cache Python packages
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
# Cache the Python package environment, excluding pip and setuptools installed by setup-python
|
|
||||||
path: |
|
|
||||||
~/.cache/pip
|
|
||||||
${{ env.pythonLocation }}/bin/*
|
|
||||||
${{ env.pythonLocation }}/include
|
|
||||||
${{ env.pythonLocation }}/lib/python*/site-packages/*
|
|
||||||
!${{ env.pythonLocation }}/bin/pip*
|
|
||||||
!${{ env.pythonLocation }}/lib/python*/site-packages/pip*
|
|
||||||
!${{ env.pythonLocation }}/lib/python*/site-packages/setuptools*
|
|
||||||
key: ${{ env.pythonLocation }}-${{ hashFiles('docs/requirements.txt') }}
|
|
||||||
- name: Install Doxygen and Latex dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install doxygen texlive-xetex texlive-binaries texlive-lang-english latexmk fonts-freefont-otf
|
|
||||||
- name: Install requirements
|
|
||||||
run: |
|
|
||||||
pip install -r docs/requirements.txt
|
|
||||||
- name: Setup Emscripten cache
|
|
||||||
id: cache-system-libraries
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ${{env.EM_CACHE_FOLDER}}
|
|
||||||
key: ${{env.EM_VERSION}}-${{ runner.os }}
|
|
||||||
- uses: mymindstorm/setup-emsdk@v9
|
|
||||||
with:
|
|
||||||
version: ${{env.EM_VERSION}}
|
|
||||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
|
||||||
- name: ccache
|
|
||||||
uses: hendrikmuhs/ccache-action@v1
|
|
||||||
- name: Build examples (with cache)
|
|
||||||
run: scripts/build_html_examples.sh
|
|
||||||
- name: Build docs
|
|
||||||
run: docs/build.py
|
|
||||||
- name: Remove .doctrees
|
|
||||||
run: rm -rf out_html/.doctrees
|
|
||||||
- name: Retrieve version
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=VERSION_NAME::$(scripts/find_version.sh)"
|
|
||||||
id: version
|
|
||||||
- name: Deploy to subfolder
|
|
||||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ACCESS_TOKEN: ${{ secrets.LVGL_BOT_TOKEN }}
|
|
||||||
REPOSITORY_NAME: lvgl/docs
|
|
||||||
BRANCH: gh-pages # The branch the action should deploy to.
|
|
||||||
FOLDER: out_html # The folder the action should deploy.
|
|
||||||
TARGET_FOLDER: ${{ steps.version.outputs.VERSION_NAME }}
|
|
||||||
GIT_CONFIG_NAME: lvgl-bot
|
|
||||||
GIT_CONFIG_EMAIL: lvgl-bot@users.noreply.github.com
|
|
||||||
PRESERVE: true
|
|
||||||
SINGLE_COMMIT: true
|
|
||||||
- name: Deploy to master
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ACCESS_TOKEN: ${{ secrets.LVGL_BOT_TOKEN }}
|
|
||||||
REPOSITORY_NAME: lvgl/docs
|
|
||||||
BRANCH: gh-pages # The branch the action should deploy to.
|
|
||||||
FOLDER: out_html # The folder the action should deploy.
|
|
||||||
TARGET_FOLDER: master
|
|
||||||
GIT_CONFIG_NAME: lvgl-bot
|
|
||||||
GIT_CONFIG_EMAIL: lvgl-bot@users.noreply.github.com
|
|
||||||
PRESERVE: true
|
|
||||||
SINGLE_COMMIT: true
|
|
@ -1,23 +0,0 @@
|
|||||||
name: Push LVGL release to Espressif Component Service
|
|
||||||
|
|
||||||
# If the commit is tagged, it will be uploaded. Other scenario silently fail.
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
upload_components:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@master
|
|
||||||
with:
|
|
||||||
submodules: "recursive"
|
|
||||||
|
|
||||||
- name: Upload component to component registry
|
|
||||||
uses: espressif/github-actions/upload_components@master
|
|
||||||
with:
|
|
||||||
name: "lvgl"
|
|
||||||
version: "git"
|
|
||||||
namespace: "lvgl"
|
|
||||||
api_token: ${{ secrets.ESP_IDF_COMPONENT_API_TOKEN }}
|
|
16
bsp/swm320/APP/lvgl/.github/workflows/main.yml
vendored
16
bsp/swm320/APP/lvgl/.github/workflows/main.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [opened, edited]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
auto_close_issues:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v1
|
|
||||||
- name: Automatically close issues that don't follow the issue template
|
|
||||||
uses: lucasbento/auto-close-issues@v1.0.2
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
issue-close-message: "@${issue.user.login}: hello! :wave:\n\nThis issue is being automatically closed because it does not follow the issue template." # optional property
|
|
||||||
closed-issues-label: "not-template"
|
|
@ -1,21 +0,0 @@
|
|||||||
name: Check Makefile
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master, release/v8.* ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Build using Makefile
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
- name: Install prerequisites
|
|
||||||
run: scripts/install-prerequisites.sh
|
|
||||||
- name: Build
|
|
||||||
working-directory: tests/makefile
|
|
||||||
run: make test_file
|
|
@ -1,27 +0,0 @@
|
|||||||
on:
|
|
||||||
push:
|
|
||||||
# Sequence of patterns matched against refs/tags
|
|
||||||
tags:
|
|
||||||
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
|
|
||||||
|
|
||||||
name: Create Release
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Create Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Create Release
|
|
||||||
id: create_release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: Release ${{ github.ref }}
|
|
||||||
body: |
|
|
||||||
See the [CHANGELOG](https://github.com/lvgl/lvgl/blob/master/docs/CHANGELOG.md)
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
27
bsp/swm320/APP/lvgl/.gitignore
vendored
27
bsp/swm320/APP/lvgl/.gitignore
vendored
@ -1,27 +0,0 @@
|
|||||||
**/*.o
|
|
||||||
**/*bin
|
|
||||||
**/*.swp
|
|
||||||
**/*.swo
|
|
||||||
**/*.gcda
|
|
||||||
**/*.gcno
|
|
||||||
tags
|
|
||||||
docs/api_doc
|
|
||||||
scripts/cppcheck_res.txt
|
|
||||||
scripts/built_in_font/lv_font_*
|
|
||||||
docs/doxygen_html
|
|
||||||
docs/xml
|
|
||||||
docs/examples.md
|
|
||||||
docs/out_latex
|
|
||||||
docs/_static/built_lv_examples
|
|
||||||
docs/LVGL.pdf
|
|
||||||
docs/env
|
|
||||||
out_html
|
|
||||||
__pycache__
|
|
||||||
/emscripten_builder
|
|
||||||
test_screenshot_error.h
|
|
||||||
build/
|
|
||||||
tests/build_*/
|
|
||||||
tests/report/
|
|
||||||
.DS_Store
|
|
||||||
.vscode
|
|
||||||
*.bak
|
|
@ -1,30 +0,0 @@
|
|||||||
# See https://pre-commit.com for more information
|
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v3.2.0
|
|
||||||
hooks:
|
|
||||||
- id: trailing-whitespace
|
|
||||||
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
# Run astyle over the staged files with c and h extension found in the directories
|
|
||||||
# listed in the files regex pattern. Ignoring the files in the exclude pattern.
|
|
||||||
- id: format-source
|
|
||||||
name: Formatting source files
|
|
||||||
entry: astyle --options=scripts/code-format.cfg --ignore-exclude-errors
|
|
||||||
stages: [ commit ]
|
|
||||||
language: system
|
|
||||||
pass_filenames: true
|
|
||||||
verbose: true
|
|
||||||
files: |
|
|
||||||
(?x)^(
|
|
||||||
src/ |
|
|
||||||
tests/src/test_cases/
|
|
||||||
)
|
|
||||||
exclude: |
|
|
||||||
(?x)^(
|
|
||||||
src/extra/libs/ |
|
|
||||||
src/lv_conf_internal.h
|
|
||||||
)
|
|
||||||
types_or: ["c", "header"]
|
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
|||||||
MIT licence
|
|
||||||
Copyright (c) 2021 LVGL Kft
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,186 +0,0 @@
|
|||||||
<h1 align="center"> LVGL - Light and Versatile Graphics Library</h1>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="https://lvgl.io/assets/images/lvgl_widgets_demo.gif">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
LVGL provides everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h4 align="center">
|
|
||||||
<a href="https://lvgl.io">Website </a> ·
|
|
||||||
<a href="https://docs.lvgl.io/">Docs</a> ·
|
|
||||||
<a href="https://forum.lvgl.io">Forum</a> ·
|
|
||||||
<a href="https://lvgl.io/services">Services</a> ·
|
|
||||||
<a href="https://docs.lvgl.io/master/examples.html">Interactive examples</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
|
|
||||||
**English** | [中文](./README_zh.md) | [Português do Brasil](./README_pt_BR.md)
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### Table of content
|
|
||||||
- [Overview](#overview)
|
|
||||||
- [Get started](#get-started)
|
|
||||||
- [Examples](#examples)
|
|
||||||
- [Services](#services)
|
|
||||||
- [Contributing](#contributing)
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
### Features
|
|
||||||
* Powerful [building blocks](https://docs.lvgl.io/master/widgets/index.html): buttons, charts, lists, sliders, images, etc.
|
|
||||||
* Advanced graphics engine: animations, anti-aliasing, opacity, smooth scrolling, blending modes, etc
|
|
||||||
* Supports [various input devices](https://docs.lvgl.io/master/overview/indev.html): touchscreen, mouse, keyboard, encoder, buttons, etc.
|
|
||||||
* Supports [multiple displays](https://docs.lvgl.io/master/overview/display.html)
|
|
||||||
* Hardware independent, can be use with any microcontroller and display
|
|
||||||
* Scalable to operate with little memory (64 kB Flash, 16 kB RAM)
|
|
||||||
* Multi-language support with UTF-8 handling, CJK, Bidirectional and Arabic script support
|
|
||||||
* Fully customizable graphical elements via [CSS-like styles](https://docs.lvgl.io/master/overview/style.html)
|
|
||||||
* Powerful layouts inspired by CSS: [Flexbox](https://docs.lvgl.io/master/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/layouts/grid.html)
|
|
||||||
* OS, External memory and GPU are supported but not required. (built in support for STM32 DMA2D, SWM341 DMA2D, and NXP PXP and VGLite)
|
|
||||||
* Smooth rendering even with a [single frame buffer](https://docs.lvgl.io/master/porting/display.html)
|
|
||||||
* Written in C and compatible with C++
|
|
||||||
* Micropython Binding exposes [LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings)
|
|
||||||
* [Simulator](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) to develop on PC without embedded hardware
|
|
||||||
* 100+ simple [Examples](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
* [Documentation](http://docs.lvgl.io/) and API references online and in PDF
|
|
||||||
|
|
||||||
### Requirements
|
|
||||||
Basically, every modern controller (which is able to drive a display) is suitable to run LVGL. The minimal requirements are:
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Name</strong> </td>
|
|
||||||
<td><strong>Minimal</strong></td>
|
|
||||||
<td><strong>Recommended</strong></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><strong>Architecture</strong></td>
|
|
||||||
<td colspan="2">16, 32 or 64 bit microcontroller or processor</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Clock</strong></td>
|
|
||||||
<td> > 16 MHz </td>
|
|
||||||
<td> > 48 MHz</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Flash/ROM</strong></td>
|
|
||||||
<td> > 64 kB </td>
|
|
||||||
<td> > 180 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Static RAM</strong></td>
|
|
||||||
<td> > 16 kB </td>
|
|
||||||
<td> > 48 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Draw buffer</strong></td>
|
|
||||||
<td> > 1 × <em>hor. res.</em> pixels </td>
|
|
||||||
<td> > 1/10 screen size </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Compiler</strong></td>
|
|
||||||
<td colspan="2"> C99 or newer </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
*Note that the memory usage might vary depending on the architecture, compiler and build options.*
|
|
||||||
|
|
||||||
### Supported platforms
|
|
||||||
LVGL is completely platform independent and can be used with any MCU that fulfills the requirements.
|
|
||||||
Just to mention some platforms:
|
|
||||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
|
||||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
|
||||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
|
||||||
- [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb)
|
|
||||||
- [Raspberry Pi](https://github.com/lvgl/lv_port_linux_frame_buffer)
|
|
||||||
- [Espressif ESP32](https://github.com/lvgl/lv_port_esp32)
|
|
||||||
- [Infineon Aurix](https://github.com/lvgl/lv_port_aurix)
|
|
||||||
- Nordic NRF52 Bluetooth modules
|
|
||||||
- Quectel modems
|
|
||||||
- [SYNWIT SWM341](http://www.synwit.cn/)
|
|
||||||
|
|
||||||
LVGL is also available as:
|
|
||||||
- [Arduino library](https://docs.lvgl.io/master/get-started/platforms/arduino.html)
|
|
||||||
- [PlatformIO package](https://registry.platformio.org/libraries/lvgl/lvgl)
|
|
||||||
- [Zephyr library](https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_LVGL.html)
|
|
||||||
- [ESP32 component](https://docs.lvgl.io/master/get-started/platforms/espressif.html)
|
|
||||||
- [NXP MCUXpresso component](https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY)
|
|
||||||
- [NuttX library](https://docs.lvgl.io/master/get-started/os/nuttx.html)
|
|
||||||
- [RT-Thread RTOS](https://docs.lvgl.io/master/get-started/os/rt-thread.html)
|
|
||||||
|
|
||||||
|
|
||||||
## Get started
|
|
||||||
This list shows the recommended way of learning the library:
|
|
||||||
1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes)
|
|
||||||
2. Read the [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes)
|
|
||||||
3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/get-started/quick-overview.html) page (15 minutes)
|
|
||||||
4. Set up a [Simulator](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) (10 minutes)
|
|
||||||
5. Try out some [Examples](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_)
|
|
||||||
7. Read the [Overview](https://docs.lvgl.io/master/overview/index.html) page to get a better understanding of the library (2-3 hours)
|
|
||||||
8. Check the documentation of the [Widgets](https://docs.lvgl.io/master/widgets/index.html) to see their features and usage
|
|
||||||
9. If you have questions go to the [Forum](http://forum.lvgl.io/)
|
|
||||||
10. Read the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) guide to see how you can help to improve LVGL (15 minutes)
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
For more examples see the [examples](https://github.com/lvgl/lvgl/tree/master/examples) folder.
|
|
||||||
|
|
||||||
![LVGL button with label example](https://github.com/lvgl/lvgl/raw/master/docs/misc/btn_example.png)
|
|
||||||
|
|
||||||
### C
|
|
||||||
```c
|
|
||||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button to the current screen*/
|
|
||||||
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
|
|
||||||
lv_obj_set_size(btn, 100, 50); /*Set its size*/
|
|
||||||
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/
|
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(btn); /*Add a label to the button*/
|
|
||||||
lv_label_set_text(label, "Button"); /*Set the labels text*/
|
|
||||||
lv_obj_center(label); /*Align the label to the center*/
|
|
||||||
...
|
|
||||||
|
|
||||||
void btn_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
printf("Clicked\n");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
### Micropython
|
|
||||||
Learn more about [Micropython](https://docs.lvgl.io/master/get-started/bindings/micropython.html).
|
|
||||||
```python
|
|
||||||
def btn_event_cb(e):
|
|
||||||
print("Clicked")
|
|
||||||
|
|
||||||
# Create a Button and a Label
|
|
||||||
btn = lv.btn(lv.scr_act())
|
|
||||||
btn.set_pos(10, 10)
|
|
||||||
btn.set_size(100, 50)
|
|
||||||
btn.add_event_cb(btn_event_cb, lv.EVENT.CLICKED, None)
|
|
||||||
|
|
||||||
label = lv.label(btn)
|
|
||||||
label.set_text("Button")
|
|
||||||
label.center()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Services
|
|
||||||
LVGL Kft was established to provide a solid background for LVGL library. We offer several type of services to help you in UI development:
|
|
||||||
- Graphics design
|
|
||||||
- UI implementation
|
|
||||||
- Consulting/Support
|
|
||||||
|
|
||||||
For more information see https://lvgl.io/services
|
|
||||||
Feel free to contact us if you have any questions.
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
LVGL is an open project and contribution is very welcome. There are many ways to contribute from simply speaking about your project, through writing examples, improving the documentation, fixing bugs to hosting your own project under the LVGL organization.
|
|
||||||
|
|
||||||
For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) section of the documentation.
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
|||||||
<h1 align="center"> LVGL - Biblioteca gráfica leve e versátil</h1>
|
|
||||||
<p align="center">
|
|
||||||
<img src="https://lvgl.io/assets/images/lvgl_widgets_demo.gif">
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
O LVGL fornece tudo o que você precisa para criar uma GUI incorporada com elementos gráficos fáceis de usar, belos efeitos visuais e um baixo consumo de memória.
|
|
||||||
</p>
|
|
||||||
<h4 align="center">
|
|
||||||
<a href="https://lvgl.io">Site</a> ·
|
|
||||||
<a href="https://docs.lvgl.io/">Documentação</a> ·
|
|
||||||
<a href="https://forum.lvgl.io">Fórum</a> ·
|
|
||||||
<a href="https://lvgl.io/services">Serviços</a> ·
|
|
||||||
<a href="https://docs.lvgl.io/master/examples.html">Exemplos interativos</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
[English](./README.md) | [中文](./README_zh.md) | **Português do Brasil**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Tabela de conteúdo
|
|
||||||
|
|
||||||
- [Visão Geral](#visão-geral)
|
|
||||||
- [Iniciando](#iniciando)
|
|
||||||
- [Exemplos](#exemplos)
|
|
||||||
- [Serviços](#serviços)
|
|
||||||
- [Contribuindo](#contribuindo)
|
|
||||||
|
|
||||||
## Visão Geral
|
|
||||||
|
|
||||||
### Recursos
|
|
||||||
* Poderosos [widgets](https://docs.lvgl.io/master/widgets/index.html): botões, gráficos, listas, controles deslizantes (sliders), imagens, etc.
|
|
||||||
* Mecanismo gráfico avançado: animações, anti-aliasing, opacidade, rolagem suave, modos de mesclagem (blending modes), etc.
|
|
||||||
* Suporte à [vários dispositivos de entrada](https://docs.lvgl.io/master/overview/indev.html): tela sensível ao toque, mouse, teclado, codificador, botões, etc.
|
|
||||||
* Suporte à [vários monitores](https://docs.lvgl.io/master/overview/display.html)
|
|
||||||
* Pode ser usado com qualquer microcontrolador e display, independente do hardware
|
|
||||||
* Escalável para operar com pouca memória (64 kB Flash, 16 kB RAM)
|
|
||||||
* Suporte multilíngue com manipulação UTF-8, suporte ao alfabeto bidirecional, árabe e CJK (Chinês, Japonês e Coreano)
|
|
||||||
* Elementos gráficos totalmente personalizáveis por meio de [CSS](https://docs.lvgl.io/master/overview/style.html)
|
|
||||||
* Layouts poderosos inspirados em CSS: [Flexbox](https://docs.lvgl.io/master/layouts/flex.html) e [Grid](https://docs.lvgl.io/master/layouts/grid.html)
|
|
||||||
* SO, memória externa e GPU são suportados, mas não obrigatórios. (suporte integrado para STM32 DMA2D, SWM341 DMA2D e NXP PXP e VGLite)
|
|
||||||
* Renderização suave mesmo com um [buffer de quadro único](https://docs.lvgl.io/master/porting/display.html) (single frame buffer)
|
|
||||||
* Escrito em C e compatível com C++
|
|
||||||
* Uso do LittlevGL com Micropython simplificado com [LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings)
|
|
||||||
* [Simulador](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) para desenvolver no PC sem hardware embutido
|
|
||||||
* Mais de 100 [exemplos simples](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
* [Documentação](http://docs.lvgl.io/) e referências de API online e em PDF
|
|
||||||
|
|
||||||
### Requerimentos
|
|
||||||
Basicamente, todo controlador moderno (que é capaz de acionar um display) é adequado para executar LVGL. Os requisitos mínimos são:
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Nome</strong>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<strong>Minímo</strong>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<strong>Recomendado</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Arquitetura</strong>
|
|
||||||
</td>
|
|
||||||
<td colspan="2">Microcontrolador ou processador de 16, 32 ou 64 bits</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Clock</strong>
|
|
||||||
</td>
|
|
||||||
<td>> 16 MHz</td>
|
|
||||||
<td>> 48 MHz</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Flash/ROM</strong>
|
|
||||||
</td>
|
|
||||||
<td>> 64 kB</td>
|
|
||||||
<td>> 180 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>RAM estática</strong>
|
|
||||||
</td>
|
|
||||||
<td>> 16 kB</td>
|
|
||||||
<td>> 48 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Draw buffer</strong>
|
|
||||||
</td>
|
|
||||||
<td>> 1 × <em>hor. res.</em> pixels</td>
|
|
||||||
<td>> tamanho da tela de 1/10</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<strong>Compilador</strong>
|
|
||||||
</td>
|
|
||||||
<td colspan="2">Padrão C99 ou mais recente</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
*Observe que o uso de memória pode variar dependendo da arquitetura, do compilador e das opções de compilação.*
|
|
||||||
|
|
||||||
### Plataformas suportadas
|
|
||||||
O LVGL é completamente independente de plataforma e pode ser usado com qualquer MCU que atenda aos requisitos.
|
|
||||||
Apenas para citar algumas plataformas:
|
|
||||||
|
|
||||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
|
||||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
|
||||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
|
||||||
- [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb)
|
|
||||||
- [Raspberry Pi](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
|
||||||
- [Espressif ESP32](https://github.com/lvgl/lv_port_esp32)
|
|
||||||
- [Infineon Aurix](https://github.com/lvgl/lv_port_aurix)
|
|
||||||
- Nordic NRF52 Bluetooth modules
|
|
||||||
- Quectel modems
|
|
||||||
- [SYNWIT SWM341](https://www.synwit.cn/)
|
|
||||||
|
|
||||||
LVGL também está disponível para:
|
|
||||||
- [Arduino library](https://docs.lvgl.io/master/get-started/platforms/arduino.html)
|
|
||||||
- [PlatformIO package](https://registry.platformio.org/libraries/lvgl/lvgl)
|
|
||||||
- [Zephyr library](https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_LVGL.html)
|
|
||||||
- [ESP32 component](https://docs.lvgl.io/master/get-started/platforms/espressif.html)
|
|
||||||
- [NXP MCUXpresso component](https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY)
|
|
||||||
- [NuttX library](https://docs.lvgl.io/master/get-started/os/nuttx.html)
|
|
||||||
- [RT-Thread RTOS](https://docs.lvgl.io/master/get-started/os/rt-thread.html)
|
|
||||||
|
|
||||||
## Iniciando
|
|
||||||
Esta lista mostra a maneira recomendada de aprender sobre a biblioteca:
|
|
||||||
|
|
||||||
1. Confira as [demos on-line](https://lvgl.io/demos) para ver o LVGL em ação (3 minutos)
|
|
||||||
2. Leia a [introdução](https://docs.lvgl.io/master/intro/index.html) da documentação (5 minutos)
|
|
||||||
3. Familiarize-se com o básico da [Visão geral rápida](https://docs.lvgl.io/master/get-started/quick-overview.html) (15 minutos)
|
|
||||||
4. Configure um [simulador](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) (10 minutos)
|
|
||||||
5. Experimente alguns [Exemplos](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
6. Placa para porta LVGL. Veja o guia [porting](https://docs.lvgl.io/master/porting/index.html) ou verifique o pronto para usar [Projects](https://github.com/lvgl?q=lv_port_)
|
|
||||||
7. Leia a [visão geral](https://docs.lvgl.io/master/overview/index.html) para entender melhor a biblioteca (2-3 horas)
|
|
||||||
8. Verifique a documentação dos [widgets](https://docs.lvgl.io/master/widgets/index.html) para ver seus recursos e como utilizá-los
|
|
||||||
9. Se você tiver dúvidas, acesse o [fórum](http://forum.lvgl.io/)
|
|
||||||
10. Leia o guia de [contribuição](https://docs.lvgl.io/master/CONTRIBUTING.html) para ver como você pode ajudar a melhorar o LVGL (15 minutos)
|
|
||||||
|
|
||||||
## Exemplos
|
|
||||||
Para mais exemplos, veja a pasta [examples](https://github.com/lvgl/lvgl/tree/master/examples).
|
|
||||||
|
|
||||||
![Exemplo de botão LVGL com rótulo (label)](https://github.com/lvgl/lvgl/raw/master/docs/misc/btn_example.png)
|
|
||||||
|
|
||||||
### C
|
|
||||||
|
|
||||||
```c
|
|
||||||
lv_obj_t * button = lv_btn_create(lv_scr_act()); /* Adiciona um botão à tela atual */
|
|
||||||
lv_obj_set_pos(button, 10, 10); /* Define uma posição ao botão na tela */
|
|
||||||
lv_obj_set_size(button, 100, 50); /* Define o tamanho */
|
|
||||||
lv_obj_add_event_cb(button, button_event_callback, LV_EVENT_CLICKED, NULL); /* Atribui um retorno de chamada (callback) */
|
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(button); /* Adiciona um rótulo (label) */
|
|
||||||
lv_label_set_text(label, "Clique aqui"); /* Define o texto do rótulo (label) */
|
|
||||||
lv_obj_center(label); /* Alinha o texto ao centro */
|
|
||||||
...
|
|
||||||
|
|
||||||
void button_event_callback(lv_event_t * e)
|
|
||||||
{
|
|
||||||
printf("Clicado\n");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Micropython
|
|
||||||
Saiba mais em [Micropython](https://docs.lvgl.io/master/get-started/bindings/micropython.html)
|
|
||||||
|
|
||||||
```python
|
|
||||||
def button_event_callback(event):
|
|
||||||
print("Clicado")
|
|
||||||
|
|
||||||
# Cria um botão e um rótulo (label)
|
|
||||||
button = lv.btn(lv.scr_act())
|
|
||||||
button.set_pos(10, 10)
|
|
||||||
button.set_size(100, 50)
|
|
||||||
button.add_event_cb(button_event_callback, lv.EVENT.CLICKED, None)
|
|
||||||
|
|
||||||
label = lv.label(button)
|
|
||||||
label.set_text("Cliquq aqui")
|
|
||||||
label.center()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Serviços
|
|
||||||
O LVGL Kft foi estabelecido para fornecer uma base sólida para a biblioteca LVGL. Oferecemos vários tipos de serviços
|
|
||||||
para ajudá-lo no desenvolvimento da interface do usuário:
|
|
||||||
|
|
||||||
- Design gráfico
|
|
||||||
- Implementação de IU
|
|
||||||
- Consultoria/Suporte
|
|
||||||
|
|
||||||
Para mais informações, consulte [LVGL Serviços](https://lvgl.io/services). Sinta-se à vontade para entrar em contato
|
|
||||||
conosco se tiver alguma dúvida.
|
|
||||||
|
|
||||||
## Contribuindo
|
|
||||||
O LVGL é um projeto aberto e sua contribuição é muito bem-vinda. Há muitas maneiras de contribuir, desde simplesmente
|
|
||||||
falando sobre seu projeto, escrevendo exemplos, melhorando a documentação, corrigindo bugs até hospedar seu próprio
|
|
||||||
projeto sob a organização LVGL.
|
|
||||||
|
|
||||||
Para obter uma descrição detalhada das oportunidades de contribuição, visite a seção de [contribuição](https://docs.lvgl.io/master/CONTRIBUTING.html) da documentação.
|
|
@ -1,193 +0,0 @@
|
|||||||
<h1 align="center"> LVGL - Light and Versatile Graphics Library</h1>
|
|
||||||
<h2 align="center"> LVGL - 轻量级通用型图形库</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="https://lvgl.io/assets/images/lvgl_widgets_demo.gif">
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
LVGL是一个高度可裁剪、低资源占用、界面美观且易用的嵌入式系统图形库
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h4 align="center">
|
|
||||||
<a href="https://lvgl.io">官网</a> ·
|
|
||||||
<a href="https://docs.lvgl.io/">文档</a> ·
|
|
||||||
<a href="https://forum.lvgl.io">论坛</a> ·
|
|
||||||
<a href="https://lvgl.io/services">服务</a> ·
|
|
||||||
<a href="https://docs.lvgl.io/master/examples.html">例程</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
|
|
||||||
[English](./README.md) | **中文** | [Português do Brasil](./README_pt_BR.md)
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 目录
|
|
||||||
- [概况与总览](#概况与总览)
|
|
||||||
- [如何入门](#如何入门)
|
|
||||||
- [例程](#例程)
|
|
||||||
- [服务](#服务)
|
|
||||||
- [如何向社区贡献](#如何向社区贡献)
|
|
||||||
|
|
||||||
## 概况与总览
|
|
||||||
### 特性
|
|
||||||
* 丰富且强大的模块化[图形组件](https://docs.lvgl.io/master/widgets/index.html):按钮 (buttons)、图表 (charts)、列表 (lists)、滑动条 (sliders)、图片 (images) 等
|
|
||||||
* 高级的图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等效果
|
|
||||||
* 支持多种[输入设备](https://docs.lvgl.io/master/overview/indev.html):触摸屏、 键盘、编码器、按键等
|
|
||||||
* 支持[多显示设备](https://docs.lvgl.io/master/overview/display.html)
|
|
||||||
* 不依赖特定的硬件平台,可以在任何显示屏上运行
|
|
||||||
* 配置可裁剪(最低资源占用:64 kB Flash,16 kB RAM)
|
|
||||||
* 基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等
|
|
||||||
* 可以通过[类CSS](https://docs.lvgl.io/master/overview/style.html)的方式来设计、布局图形界面(例如:[Flexbox](https://docs.lvgl.io/master/layouts/flex.html)、[Grid](https://docs.lvgl.io/master/layouts/grid.html))
|
|
||||||
* 支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32 DMA2D、SWM341 DMA2D、NXP PXP和VGLite)
|
|
||||||
* 即便仅有[单缓冲区(frame buffer)](https://docs.lvgl.io/master/porting/display.html)的情况下,也可保证渲染如丝般顺滑
|
|
||||||
* 全部由C编写完成,并支持C++调用
|
|
||||||
* 支持Micropython编程,参见:[LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings)
|
|
||||||
* 支持[模拟器](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html)仿真,可以无硬件依托进行开发
|
|
||||||
* 丰富详实的[例程](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
* 详尽的[文档](http://docs.lvgl.io/)以及API参考手册,可线上查阅或可下载为PDF格式
|
|
||||||
|
|
||||||
### 硬件要求
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td> <strong>要求</strong> </td>
|
|
||||||
<td><strong>最低要求</strong></td>
|
|
||||||
<td><strong>建议要求</strong></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><strong>架构</strong></td>
|
|
||||||
<td colspan="2">16、32、64位微控制器或微处理器</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td> <strong>时钟</strong></td>
|
|
||||||
<td> > 16 MHz</td>
|
|
||||||
<td> > 48 MHz</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Flash/ROM</strong></td>
|
|
||||||
<td> > 64 kB </td>
|
|
||||||
<td> > 180 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Static RAM</strong></td>
|
|
||||||
<td> > 16 kB </td>
|
|
||||||
<td> > 48 kB</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>Draw buffer</strong></td>
|
|
||||||
<td> > 1 × <em>hor. res.</em> pixels </td>
|
|
||||||
<td> > 1/10屏幕大小 </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td> <strong>编译器</strong></td>
|
|
||||||
<td colspan="2"> C99或更新 </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
*注意:资源占用情况与具体硬件平台、编译器等因素有关,上表中仅给出参考值*
|
|
||||||
|
|
||||||
### 已经支持的平台
|
|
||||||
LVGL本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求的微控制器均可运行LVGL。
|
|
||||||
如下仅列举其中一部分:
|
|
||||||
|
|
||||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
|
||||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
|
||||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
|
||||||
- [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb)
|
|
||||||
- [Raspberry Pi](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
|
||||||
- [Espressif ESP32](https://github.com/lvgl/lv_port_esp32)
|
|
||||||
- [Infineon Aurix](https://github.com/lvgl/lv_port_aurix)
|
|
||||||
- Nordic NRF52 Bluetooth modules
|
|
||||||
- Quectel modems
|
|
||||||
- [SYNWIT SWM341](https://www.synwit.cn/)
|
|
||||||
|
|
||||||
LVGL也支持:
|
|
||||||
- [Arduino library](https://docs.lvgl.io/master/get-started/platforms/arduino.html)
|
|
||||||
- [PlatformIO package](https://platformio.org/lib/show/12440/lvgl)
|
|
||||||
- [Zephyr library](https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_LVGL.html)
|
|
||||||
- [ESP32 component](https://docs.lvgl.io/master/get-started/platforms/espressif.html)
|
|
||||||
- [NXP MCUXpresso component](https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY)
|
|
||||||
- [NuttX library](https://docs.lvgl.io/master/get-started/os/nuttx.html)
|
|
||||||
- [RT-Thread RTOS](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/packages-manual/lvgl-docs/introduction)
|
|
||||||
|
|
||||||
|
|
||||||
## 如何入门
|
|
||||||
请按照如下顺序来学习LVGL:
|
|
||||||
1. 使用[网页在线例程](https://lvgl.io/demos)来体验LVGL(3分钟)
|
|
||||||
2. 阅读文档[简介](https://docs.lvgl.io/master/intro/index.html)章节来初步了解LVGL(5分钟)
|
|
||||||
3. 再来阅读一下文档快速[快速概览](https://docs.lvgl.io/master/get-started/quick-overview.html)章节来了解LVGL的基本知识(15分钟)
|
|
||||||
4. 学习如何使用[模拟器](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html)来在电脑上仿真LVGL(10分钟)
|
|
||||||
5. 试着动手实践一些[例程](https://github.com/lvgl/lvgl/tree/master/examples)
|
|
||||||
6. 参考[移植指南](https://docs.lvgl.io/master/porting/index.html)尝试将LVGL移植到一块开发板上,LVGL也已经提供了一些移植好的[工程](https://github.com/lvgl?q=lv_port_)
|
|
||||||
7. 仔细阅读文档[总览](https://docs.lvgl.io/master/overview/index.html)章节来更加深入的了解和熟悉LVGL(2-3小时)
|
|
||||||
8. 浏览文档[组件(Widgets)](https://docs.lvgl.io/master/widgets/index.html)章节来了解如何使用它们
|
|
||||||
9. 如果你有问题可以到LVGL[论坛](http://forum.lvgl.io/)提问
|
|
||||||
10. 阅读文档[如何向社区贡献](https://docs.lvgl.io/master/CONTRIBUTING.html)章节来看看你能帮LVGL社区做些什么,以促进LVGL软件质量的不断提高(15分钟)
|
|
||||||
|
|
||||||
## 例程
|
|
||||||
|
|
||||||
更多例程请参见 [examples](https://github.com/lvgl/lvgl/tree/master/examples) 文件夹。
|
|
||||||
|
|
||||||
![LVGL button with label example](https://github.com/lvgl/lvgl/raw/master/docs/misc/btn_example.png)
|
|
||||||
|
|
||||||
### C
|
|
||||||
```c
|
|
||||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button to the current screen*/
|
|
||||||
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
|
|
||||||
lv_obj_set_size(btn, 100, 50); /*Set its size*/
|
|
||||||
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/
|
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(btn); /*Add a label to the button*/
|
|
||||||
lv_label_set_text(label, "Button"); /*Set the labels text*/
|
|
||||||
lv_obj_center(label); /*Align the label to the center*/
|
|
||||||
...
|
|
||||||
|
|
||||||
void btn_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
printf("Clicked\n");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
### Micropython
|
|
||||||
更多信息请到 [Micropython官网](https://docs.lvgl.io/master/get-started/bindings/micropython.html) 查询.
|
|
||||||
```python
|
|
||||||
def btn_event_cb(e):
|
|
||||||
print("Clicked")
|
|
||||||
|
|
||||||
# Create a Button and a Label
|
|
||||||
btn = lv.btn(lv.scr_act())
|
|
||||||
btn.set_pos(10, 10)
|
|
||||||
btn.set_size(100, 50)
|
|
||||||
btn.add_event_cb(btn_event_cb, lv.EVENT.CLICKED, None)
|
|
||||||
|
|
||||||
label = lv.label(btn)
|
|
||||||
label.set_text("Button")
|
|
||||||
label.center()
|
|
||||||
```
|
|
||||||
|
|
||||||
## 服务
|
|
||||||
LVGL 责任有限公司成立的目的是为了给用户使用LVGL图形库提供额外的技术支持,我们致力于提供以下服务:
|
|
||||||
|
|
||||||
- 图形设计
|
|
||||||
- UI设计
|
|
||||||
- 技术咨询以及技术支持
|
|
||||||
|
|
||||||
更多信息请参见 https://lvgl.io/services ,如果有任何问题请随时联系我们。
|
|
||||||
|
|
||||||
|
|
||||||
## 如何向社区贡献
|
|
||||||
LVGL是一个开源项目,非常欢迎您参与到社区贡献当中。您有很多种方式来为提高LVGL贡献您的一份力量,包括但不限于:
|
|
||||||
|
|
||||||
- 介绍你基于LVGL设计的作品或项目
|
|
||||||
- 写一些例程
|
|
||||||
- 修改以及完善文档
|
|
||||||
- 修复bug
|
|
||||||
|
|
||||||
请参见文档[如何向社区贡献](https://docs.lvgl.io/master/CONTRIBUTING.html)章节来获取更多信息。
|
|
@ -1,11 +0,0 @@
|
|||||||
# RT-Thread building script for bridge
|
|
||||||
|
|
||||||
import os
|
|
||||||
from building import *
|
|
||||||
|
|
||||||
objs = []
|
|
||||||
cwd = GetCurrentDir()
|
|
||||||
|
|
||||||
objs = objs + SConscript(cwd + '/env_support/rt-thread/SConscript')
|
|
||||||
|
|
||||||
Return('objs')
|
|
@ -1,34 +0,0 @@
|
|||||||
# ESP-IDF component file for make based commands
|
|
||||||
|
|
||||||
COMPONENT_SRCDIRS := . \
|
|
||||||
src \
|
|
||||||
src/core \
|
|
||||||
src/draw \
|
|
||||||
src/extra \
|
|
||||||
src/font \
|
|
||||||
src/gpu \
|
|
||||||
src/hal \
|
|
||||||
src/misc \
|
|
||||||
src/widgets \
|
|
||||||
src/extra/layouts \
|
|
||||||
src/extra/layouts/flex \
|
|
||||||
src/extra/layouts/grid \
|
|
||||||
src/extra/themes \
|
|
||||||
src/extra/themes/basic \
|
|
||||||
src/extra/themes/default \
|
|
||||||
src/extra/widgets/calendar \
|
|
||||||
src/extra/widgets/colorwheel \
|
|
||||||
src/extra/widgets \
|
|
||||||
src/extra/widgets/imgbtn \
|
|
||||||
src/extra/widgets/keyboard \
|
|
||||||
src/extra/widgets/led \
|
|
||||||
src/extra/widgets/list \
|
|
||||||
src/extra/widgets/msgbox \
|
|
||||||
src/extra/widgets/spinbox \
|
|
||||||
src/extra/widgets/spinner \
|
|
||||||
src/extra/widgets/tabview \
|
|
||||||
src/extra/widgets/tileview \
|
|
||||||
src/extra/widgets/win
|
|
||||||
|
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := $(COMPONENT_SRCDIRS) .
|
|
@ -1,2 +0,0 @@
|
|||||||
description: LVGL - Light and Versatile Graphics Library
|
|
||||||
url: https://github.com/lvgl/lvgl
|
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "lvgl",
|
|
||||||
"version": "8.3.1",
|
|
||||||
"keywords": "graphics, gui, embedded, tft, lvgl",
|
|
||||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/lvgl/lvgl.git"
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"includeDir": "."
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"homepage": "https://lvgl.io",
|
|
||||||
"frameworks": "*",
|
|
||||||
"platforms": "*"
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
name=lvgl
|
|
||||||
version=8.3.1
|
|
||||||
author=kisvegabor
|
|
||||||
maintainer=kisvegabor,embeddedt,pete-pjb
|
|
||||||
sentence=Full-featured Graphics Library for Embedded Systems
|
|
||||||
paragraph=Powerful and easy-to-use embedded GUI with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash).
|
|
||||||
category=Display
|
|
||||||
url=https://lvgl.io
|
|
||||||
architectures=*
|
|
||||||
includes=lvgl.h
|
|
@ -1,759 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_conf.h
|
|
||||||
* Configuration file for v8.3.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy this file as `lv_conf.h`
|
|
||||||
* 1. simply next to the `lvgl` folder
|
|
||||||
* 2. or any other places and
|
|
||||||
* - define `LV_CONF_INCLUDE_SIMPLE`
|
|
||||||
* - add the path as include path
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
#if 0 /*Set it to "1" to enable content*/
|
|
||||||
|
|
||||||
#ifndef LV_CONF_H
|
|
||||||
#define LV_CONF_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/*====================
|
|
||||||
COLOR SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
|
|
||||||
#define LV_COLOR_DEPTH 16
|
|
||||||
|
|
||||||
/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
|
|
||||||
#define LV_COLOR_16_SWAP 0
|
|
||||||
|
|
||||||
/*Enable features to draw on transparent background.
|
|
||||||
*It's required if opa, and transform_* style properties are used.
|
|
||||||
*Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/
|
|
||||||
#define LV_COLOR_SCREEN_TRANSP 0
|
|
||||||
|
|
||||||
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
|
|
||||||
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
|
|
||||||
#define LV_COLOR_MIX_ROUND_OFS 0
|
|
||||||
|
|
||||||
/*Images pixels with this color will not be drawn if they are chroma keyed)*/
|
|
||||||
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/
|
|
||||||
|
|
||||||
/*=========================
|
|
||||||
MEMORY SETTINGS
|
|
||||||
*=========================*/
|
|
||||||
|
|
||||||
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
|
|
||||||
#define LV_MEM_CUSTOM 0
|
|
||||||
#if LV_MEM_CUSTOM == 0
|
|
||||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
|
||||||
#define LV_MEM_SIZE (48U * 1024U) /*[bytes]*/
|
|
||||||
|
|
||||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
|
||||||
#define LV_MEM_ADR 0 /*0: unused*/
|
|
||||||
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
|
|
||||||
#if LV_MEM_ADR == 0
|
|
||||||
#undef LV_MEM_POOL_INCLUDE
|
|
||||||
#undef LV_MEM_POOL_ALLOC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /*LV_MEM_CUSTOM*/
|
|
||||||
#define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
|
||||||
#define LV_MEM_CUSTOM_ALLOC malloc
|
|
||||||
#define LV_MEM_CUSTOM_FREE free
|
|
||||||
#define LV_MEM_CUSTOM_REALLOC realloc
|
|
||||||
#endif /*LV_MEM_CUSTOM*/
|
|
||||||
|
|
||||||
/*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms.
|
|
||||||
*You will see an error log message if there wasn't enough buffers. */
|
|
||||||
#define LV_MEM_BUF_MAX_NUM 16
|
|
||||||
|
|
||||||
/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/
|
|
||||||
#define LV_MEMCPY_MEMSET_STD 0
|
|
||||||
|
|
||||||
/*====================
|
|
||||||
HAL SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
|
||||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
|
||||||
|
|
||||||
/*Input device read period in milliseconds*/
|
|
||||||
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/
|
|
||||||
|
|
||||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
|
||||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
|
||||||
#define LV_TICK_CUSTOM 0
|
|
||||||
#if LV_TICK_CUSTOM
|
|
||||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
|
||||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
|
||||||
#endif /*LV_TICK_CUSTOM*/
|
|
||||||
|
|
||||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
|
||||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
|
||||||
#define LV_DPI_DEF 130 /*[px/inch]*/
|
|
||||||
|
|
||||||
/*=======================
|
|
||||||
* FEATURE CONFIGURATION
|
|
||||||
*=======================*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Drawing
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable complex draw engine.
|
|
||||||
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
|
|
||||||
#define LV_DRAW_COMPLEX 1
|
|
||||||
#if LV_DRAW_COMPLEX != 0
|
|
||||||
|
|
||||||
/*Allow buffering some shadow calculation.
|
|
||||||
*LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
|
|
||||||
*Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
|
||||||
#define LV_SHADOW_CACHE_SIZE 0
|
|
||||||
|
|
||||||
/* Set number of maximally cached circle data.
|
|
||||||
* The circumference of 1/4 circle are saved for anti-aliasing
|
|
||||||
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
|
|
||||||
* 0: to disable caching */
|
|
||||||
#define LV_CIRCLE_CACHE_SIZE 4
|
|
||||||
#endif /*LV_DRAW_COMPLEX*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer
|
|
||||||
* and blend it as an image with the given opacity.
|
|
||||||
* Note that `bg_opa`, `text_opa` etc don't require buffering into layer)
|
|
||||||
* The widget can be buffered in smaller chunks to avoid using large buffers.
|
|
||||||
*
|
|
||||||
* - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it
|
|
||||||
* - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated.
|
|
||||||
*
|
|
||||||
* Both buffer sizes are in bytes.
|
|
||||||
* "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers
|
|
||||||
* and can't be drawn in chunks. So these settings affects only widgets with opacity.
|
|
||||||
*/
|
|
||||||
#define LV_LAYER_SIMPLE_BUF_SIZE (24 * 1024)
|
|
||||||
#define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024)
|
|
||||||
|
|
||||||
/*Default image cache size. Image caching keeps the images opened.
|
|
||||||
*If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added)
|
|
||||||
*With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
|
||||||
*However the opened images might consume additional RAM.
|
|
||||||
*0: to disable caching*/
|
|
||||||
#define LV_IMG_CACHE_DEF_SIZE 0
|
|
||||||
|
|
||||||
/*Number of stops allowed per gradient. Increase this to allow more stops.
|
|
||||||
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
|
|
||||||
#define LV_GRADIENT_MAX_STOPS 2
|
|
||||||
|
|
||||||
/*Default gradient buffer size.
|
|
||||||
*When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
|
|
||||||
*LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
|
|
||||||
*If the cache is too small the map will be allocated only while it's required for the drawing.
|
|
||||||
*0 mean no caching.*/
|
|
||||||
#define LV_GRAD_CACHE_DEF_SIZE 0
|
|
||||||
|
|
||||||
/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
|
|
||||||
*LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
|
|
||||||
*The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
|
|
||||||
#define LV_DITHER_GRADIENT 0
|
|
||||||
#if LV_DITHER_GRADIENT
|
|
||||||
/*Add support for error diffusion dithering.
|
|
||||||
*Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
|
|
||||||
*The increase in memory consumption is (24 bits * object's width)*/
|
|
||||||
#define LV_DITHER_ERROR_DIFFUSION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Maximum buffer size to allocate for rotation.
|
|
||||||
*Only used if software rotation is enabled in the display driver.*/
|
|
||||||
#define LV_DISP_ROT_MAX_BUF (10*1024)
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* GPU
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Use Arm's 2D acceleration library Arm-2D */
|
|
||||||
#define LV_USE_GPU_ARM2D 0
|
|
||||||
|
|
||||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
|
||||||
#define LV_USE_GPU_STM32_DMA2D 0
|
|
||||||
#if LV_USE_GPU_STM32_DMA2D
|
|
||||||
/*Must be defined to include path of CMSIS header of target processor
|
|
||||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
|
||||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use SWM341's DMA2D GPU*/
|
|
||||||
#define LV_USE_GPU_SWM341_DMA2D 0
|
|
||||||
#if LV_USE_GPU_SWM341_DMA2D
|
|
||||||
#define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use NXP's PXP GPU iMX RTxxx platforms*/
|
|
||||||
#define LV_USE_GPU_NXP_PXP 0
|
|
||||||
#if LV_USE_GPU_NXP_PXP
|
|
||||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
|
||||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
|
||||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
|
||||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
|
||||||
*/
|
|
||||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Use NXP's VG-Lite GPU iMX RTxxx platforms*/
|
|
||||||
#define LV_USE_GPU_NXP_VG_LITE 0
|
|
||||||
|
|
||||||
/*Use SDL renderer API*/
|
|
||||||
#define LV_USE_GPU_SDL 0
|
|
||||||
#if LV_USE_GPU_SDL
|
|
||||||
#define LV_GPU_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
|
||||||
/*Texture cache size, 8MB by default*/
|
|
||||||
#define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8)
|
|
||||||
/*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/
|
|
||||||
#define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Logging
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable the log module*/
|
|
||||||
#define LV_USE_LOG 0
|
|
||||||
#if LV_USE_LOG
|
|
||||||
|
|
||||||
/*How important log should be added:
|
|
||||||
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
|
||||||
*LV_LOG_LEVEL_INFO Log important events
|
|
||||||
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
|
||||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
|
||||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
|
||||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
|
||||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
|
||||||
|
|
||||||
/*1: Print the log with 'printf';
|
|
||||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
|
||||||
#define LV_LOG_PRINTF 0
|
|
||||||
|
|
||||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
|
||||||
#define LV_LOG_TRACE_MEM 1
|
|
||||||
#define LV_LOG_TRACE_TIMER 1
|
|
||||||
#define LV_LOG_TRACE_INDEV 1
|
|
||||||
#define LV_LOG_TRACE_DISP_REFR 1
|
|
||||||
#define LV_LOG_TRACE_EVENT 1
|
|
||||||
#define LV_LOG_TRACE_OBJ_CREATE 1
|
|
||||||
#define LV_LOG_TRACE_LAYOUT 1
|
|
||||||
#define LV_LOG_TRACE_ANIM 1
|
|
||||||
|
|
||||||
#endif /*LV_USE_LOG*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Asserts
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*Enable asserts if an operation is failed or an invalid data is found.
|
|
||||||
*If LV_USE_LOG is enabled an error message will be printed on failure*/
|
|
||||||
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/
|
|
||||||
#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
|
||||||
#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
|
|
||||||
|
|
||||||
/*Add a custom handler when assert happens e.g. to restart the MCU*/
|
|
||||||
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
|
|
||||||
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
|
|
||||||
|
|
||||||
/*-------------
|
|
||||||
* Others
|
|
||||||
*-----------*/
|
|
||||||
|
|
||||||
/*1: Show CPU usage and FPS count*/
|
|
||||||
#define LV_USE_PERF_MONITOR 0
|
|
||||||
#if LV_USE_PERF_MONITOR
|
|
||||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*1: Show the used memory and the memory fragmentation
|
|
||||||
* Requires LV_MEM_CUSTOM = 0*/
|
|
||||||
#define LV_USE_MEM_MONITOR 0
|
|
||||||
#if LV_USE_MEM_MONITOR
|
|
||||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*1: Draw random colored rectangles over the redrawn areas*/
|
|
||||||
#define LV_USE_REFR_DEBUG 0
|
|
||||||
|
|
||||||
/*Change the built in (v)snprintf functions*/
|
|
||||||
#define LV_SPRINTF_CUSTOM 0
|
|
||||||
#if LV_SPRINTF_CUSTOM
|
|
||||||
#define LV_SPRINTF_INCLUDE <stdio.h>
|
|
||||||
#define lv_snprintf snprintf
|
|
||||||
#define lv_vsnprintf vsnprintf
|
|
||||||
#else /*LV_SPRINTF_CUSTOM*/
|
|
||||||
#define LV_SPRINTF_USE_FLOAT 0
|
|
||||||
#endif /*LV_SPRINTF_CUSTOM*/
|
|
||||||
|
|
||||||
#define LV_USE_USER_DATA 1
|
|
||||||
|
|
||||||
/*Garbage Collector settings
|
|
||||||
*Used if lvgl is bound to higher level language and the memory is managed by that language*/
|
|
||||||
#define LV_ENABLE_GC 0
|
|
||||||
#if LV_ENABLE_GC != 0
|
|
||||||
#define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
|
||||||
#endif /*LV_ENABLE_GC*/
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* COMPILER SETTINGS
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*For big endian systems set to 1*/
|
|
||||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_tick_inc` function*/
|
|
||||||
#define LV_ATTRIBUTE_TICK_INC
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_timer_handler` function*/
|
|
||||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
|
||||||
|
|
||||||
/*Define a custom attribute to `lv_disp_flush_ready` function*/
|
|
||||||
#define LV_ATTRIBUTE_FLUSH_READY
|
|
||||||
|
|
||||||
/*Required alignment size for buffers*/
|
|
||||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
|
|
||||||
|
|
||||||
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
|
|
||||||
* E.g. __attribute__((aligned(4)))*/
|
|
||||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
|
||||||
|
|
||||||
/*Attribute to mark large constant arrays for example font's bitmaps*/
|
|
||||||
#define LV_ATTRIBUTE_LARGE_CONST
|
|
||||||
|
|
||||||
/*Compiler prefix for a big array declaration in RAM*/
|
|
||||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
|
||||||
|
|
||||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
|
||||||
#define LV_ATTRIBUTE_FAST_MEM
|
|
||||||
|
|
||||||
/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
|
|
||||||
#define LV_ATTRIBUTE_DMA
|
|
||||||
|
|
||||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
|
||||||
*should also appear on LVGL binding API such as Micropython.*/
|
|
||||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
|
|
||||||
|
|
||||||
/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
|
|
||||||
#define LV_USE_LARGE_COORD 0
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* FONT USAGE
|
|
||||||
*===================*/
|
|
||||||
|
|
||||||
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
|
|
||||||
*https://fonts.google.com/specimen/Montserrat*/
|
|
||||||
#define LV_FONT_MONTSERRAT_8 0
|
|
||||||
#define LV_FONT_MONTSERRAT_10 0
|
|
||||||
#define LV_FONT_MONTSERRAT_12 0
|
|
||||||
#define LV_FONT_MONTSERRAT_14 1
|
|
||||||
#define LV_FONT_MONTSERRAT_16 0
|
|
||||||
#define LV_FONT_MONTSERRAT_18 0
|
|
||||||
#define LV_FONT_MONTSERRAT_20 0
|
|
||||||
#define LV_FONT_MONTSERRAT_22 0
|
|
||||||
#define LV_FONT_MONTSERRAT_24 0
|
|
||||||
#define LV_FONT_MONTSERRAT_26 0
|
|
||||||
#define LV_FONT_MONTSERRAT_28 0
|
|
||||||
#define LV_FONT_MONTSERRAT_30 0
|
|
||||||
#define LV_FONT_MONTSERRAT_32 0
|
|
||||||
#define LV_FONT_MONTSERRAT_34 0
|
|
||||||
#define LV_FONT_MONTSERRAT_36 0
|
|
||||||
#define LV_FONT_MONTSERRAT_38 0
|
|
||||||
#define LV_FONT_MONTSERRAT_40 0
|
|
||||||
#define LV_FONT_MONTSERRAT_42 0
|
|
||||||
#define LV_FONT_MONTSERRAT_44 0
|
|
||||||
#define LV_FONT_MONTSERRAT_46 0
|
|
||||||
#define LV_FONT_MONTSERRAT_48 0
|
|
||||||
|
|
||||||
/*Demonstrate special features*/
|
|
||||||
#define LV_FONT_MONTSERRAT_12_SUBPX 0
|
|
||||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
|
|
||||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/
|
|
||||||
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
|
|
||||||
|
|
||||||
/*Pixel perfect monospace fonts*/
|
|
||||||
#define LV_FONT_UNSCII_8 0
|
|
||||||
#define LV_FONT_UNSCII_16 0
|
|
||||||
|
|
||||||
/*Optionally declare custom fonts here.
|
|
||||||
*You can use these fonts as default font too and they will be available globally.
|
|
||||||
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
|
|
||||||
#define LV_FONT_CUSTOM_DECLARE
|
|
||||||
|
|
||||||
/*Always set a default font*/
|
|
||||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
|
||||||
|
|
||||||
/*Enable handling large font and/or fonts with a lot of characters.
|
|
||||||
*The limit depends on the font size, font face and bpp.
|
|
||||||
*Compiler error will be triggered if a font needs it.*/
|
|
||||||
#define LV_FONT_FMT_TXT_LARGE 0
|
|
||||||
|
|
||||||
/*Enables/disables support for compressed fonts.*/
|
|
||||||
#define LV_USE_FONT_COMPRESSED 0
|
|
||||||
|
|
||||||
/*Enable subpixel rendering*/
|
|
||||||
#define LV_USE_FONT_SUBPX 0
|
|
||||||
#if LV_USE_FONT_SUBPX
|
|
||||||
/*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/
|
|
||||||
#define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Enable drawing placeholders when glyph dsc is not found*/
|
|
||||||
#define LV_USE_FONT_PLACEHOLDER 1
|
|
||||||
|
|
||||||
/*=================
|
|
||||||
* TEXT SETTINGS
|
|
||||||
*=================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select a character encoding for strings.
|
|
||||||
* Your IDE or editor should have the same character encoding
|
|
||||||
* - LV_TXT_ENC_UTF8
|
|
||||||
* - LV_TXT_ENC_ASCII
|
|
||||||
*/
|
|
||||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
|
||||||
|
|
||||||
/*Can break (wrap) texts on these chars*/
|
|
||||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
|
||||||
|
|
||||||
/*If a word is at least this long, will break wherever "prettiest"
|
|
||||||
*To disable, set to a value <= 0*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
|
||||||
|
|
||||||
/*Minimum number of characters in a long word to put on a line before a break.
|
|
||||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
|
||||||
|
|
||||||
/*Minimum number of characters in a long word to put on a line after a break.
|
|
||||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
|
||||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
|
||||||
|
|
||||||
/*The control character to use for signalling text recoloring.*/
|
|
||||||
#define LV_TXT_COLOR_CMD "#"
|
|
||||||
|
|
||||||
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
|
|
||||||
*The direction will be processed according to the Unicode Bidirectional Algorithm:
|
|
||||||
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
|
||||||
#define LV_USE_BIDI 0
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
/*Set the default direction. Supported values:
|
|
||||||
*`LV_BASE_DIR_LTR` Left-to-Right
|
|
||||||
*`LV_BASE_DIR_RTL` Right-to-Left
|
|
||||||
*`LV_BASE_DIR_AUTO` detect texts base direction*/
|
|
||||||
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Enable Arabic/Persian processing
|
|
||||||
*In these languages characters should be replaced with an other form based on their position in the text*/
|
|
||||||
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* WIDGET USAGE
|
|
||||||
*================*/
|
|
||||||
|
|
||||||
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
|
|
||||||
|
|
||||||
#define LV_USE_ARC 1
|
|
||||||
|
|
||||||
#define LV_USE_BAR 1
|
|
||||||
|
|
||||||
#define LV_USE_BTN 1
|
|
||||||
|
|
||||||
#define LV_USE_BTNMATRIX 1
|
|
||||||
|
|
||||||
#define LV_USE_CANVAS 1
|
|
||||||
|
|
||||||
#define LV_USE_CHECKBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
|
|
||||||
|
|
||||||
#define LV_USE_IMG 1 /*Requires: lv_label*/
|
|
||||||
|
|
||||||
#define LV_USE_LABEL 1
|
|
||||||
#if LV_USE_LABEL
|
|
||||||
#define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
|
|
||||||
#define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_LINE 1
|
|
||||||
|
|
||||||
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
|
|
||||||
#if LV_USE_ROLLER
|
|
||||||
#define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
|
||||||
|
|
||||||
#define LV_USE_SWITCH 1
|
|
||||||
|
|
||||||
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
|
|
||||||
#if LV_USE_TEXTAREA != 0
|
|
||||||
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_TABLE 1
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* EXTRA COMPONENTS
|
|
||||||
*==================*/
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Widgets
|
|
||||||
*----------*/
|
|
||||||
#define LV_USE_ANIMIMG 1
|
|
||||||
|
|
||||||
#define LV_USE_CALENDAR 1
|
|
||||||
#if LV_USE_CALENDAR
|
|
||||||
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
|
||||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
|
||||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
|
|
||||||
#else
|
|
||||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
|
||||||
#define LV_USE_CALENDAR_HEADER_ARROW 1
|
|
||||||
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
|
|
||||||
#endif /*LV_USE_CALENDAR*/
|
|
||||||
|
|
||||||
#define LV_USE_CHART 1
|
|
||||||
|
|
||||||
#define LV_USE_COLORWHEEL 1
|
|
||||||
|
|
||||||
#define LV_USE_IMGBTN 1
|
|
||||||
|
|
||||||
#define LV_USE_KEYBOARD 1
|
|
||||||
|
|
||||||
#define LV_USE_LED 1
|
|
||||||
|
|
||||||
#define LV_USE_LIST 1
|
|
||||||
|
|
||||||
#define LV_USE_MENU 1
|
|
||||||
|
|
||||||
#define LV_USE_METER 1
|
|
||||||
|
|
||||||
#define LV_USE_MSGBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_SPAN 1
|
|
||||||
#if LV_USE_SPAN
|
|
||||||
/*A line text can contain maximum num of span descriptor */
|
|
||||||
#define LV_SPAN_SNIPPET_STACK_SIZE 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LV_USE_SPINBOX 1
|
|
||||||
|
|
||||||
#define LV_USE_SPINNER 1
|
|
||||||
|
|
||||||
#define LV_USE_TABVIEW 1
|
|
||||||
|
|
||||||
#define LV_USE_TILEVIEW 1
|
|
||||||
|
|
||||||
#define LV_USE_WIN 1
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Themes
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*A simple, impressive and very complete theme*/
|
|
||||||
#define LV_USE_THEME_DEFAULT 1
|
|
||||||
#if LV_USE_THEME_DEFAULT
|
|
||||||
|
|
||||||
/*0: Light mode; 1: Dark mode*/
|
|
||||||
#define LV_THEME_DEFAULT_DARK 0
|
|
||||||
|
|
||||||
/*1: Enable grow on press*/
|
|
||||||
#define LV_THEME_DEFAULT_GROW 1
|
|
||||||
|
|
||||||
/*Default transition time in [ms]*/
|
|
||||||
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
|
|
||||||
#endif /*LV_USE_THEME_DEFAULT*/
|
|
||||||
|
|
||||||
/*A very simple theme that is a good starting point for a custom theme*/
|
|
||||||
#define LV_USE_THEME_BASIC 1
|
|
||||||
|
|
||||||
/*A theme designed for monochrome displays*/
|
|
||||||
#define LV_USE_THEME_MONO 1
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Layouts
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*A layout similar to Flexbox in CSS.*/
|
|
||||||
#define LV_USE_FLEX 1
|
|
||||||
|
|
||||||
/*A layout similar to Grid in CSS.*/
|
|
||||||
#define LV_USE_GRID 1
|
|
||||||
|
|
||||||
/*---------------------
|
|
||||||
* 3rd party libraries
|
|
||||||
*--------------------*/
|
|
||||||
|
|
||||||
/*File system interfaces for common APIs */
|
|
||||||
|
|
||||||
/*API for fopen, fread, etc*/
|
|
||||||
#define LV_USE_FS_STDIO 0
|
|
||||||
#if LV_USE_FS_STDIO
|
|
||||||
#define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for open, read, etc*/
|
|
||||||
#define LV_USE_FS_POSIX 0
|
|
||||||
#if LV_USE_FS_POSIX
|
|
||||||
#define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for CreateFile, ReadFile, etc*/
|
|
||||||
#define LV_USE_FS_WIN32 0
|
|
||||||
#if LV_USE_FS_WIN32
|
|
||||||
#define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
|
||||||
#define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
|
|
||||||
#define LV_USE_FS_FATFS 0
|
|
||||||
#if LV_USE_FS_FATFS
|
|
||||||
#define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
|
||||||
#define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PNG decoder library*/
|
|
||||||
#define LV_USE_PNG 0
|
|
||||||
|
|
||||||
/*BMP decoder library*/
|
|
||||||
#define LV_USE_BMP 0
|
|
||||||
|
|
||||||
/* JPG + split JPG decoder library.
|
|
||||||
* Split JPG is a custom format optimized for embedded systems. */
|
|
||||||
#define LV_USE_SJPG 0
|
|
||||||
|
|
||||||
/*GIF decoder library*/
|
|
||||||
#define LV_USE_GIF 0
|
|
||||||
|
|
||||||
/*QR code library*/
|
|
||||||
#define LV_USE_QRCODE 0
|
|
||||||
|
|
||||||
/*FreeType library*/
|
|
||||||
#define LV_USE_FREETYPE 0
|
|
||||||
#if LV_USE_FREETYPE
|
|
||||||
/*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
|
|
||||||
#define LV_FREETYPE_CACHE_SIZE (16 * 1024)
|
|
||||||
#if LV_FREETYPE_CACHE_SIZE >= 0
|
|
||||||
/* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
|
|
||||||
/* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
|
|
||||||
/* if font size >= 256, must be configured as image cache */
|
|
||||||
#define LV_FREETYPE_SBIT_CACHE 0
|
|
||||||
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
|
|
||||||
/* (0:use system defaults) */
|
|
||||||
#define LV_FREETYPE_CACHE_FT_FACES 0
|
|
||||||
#define LV_FREETYPE_CACHE_FT_SIZES 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Rlottie library*/
|
|
||||||
#define LV_USE_RLOTTIE 0
|
|
||||||
|
|
||||||
/*FFmpeg library for image decoding and playing videos
|
|
||||||
*Supports all major image formats so do not enable other image decoder with it*/
|
|
||||||
#define LV_USE_FFMPEG 0
|
|
||||||
#if LV_USE_FFMPEG
|
|
||||||
/*Dump input information to stderr*/
|
|
||||||
#define LV_FFMPEG_DUMP_FORMAT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------
|
|
||||||
* Others
|
|
||||||
*----------*/
|
|
||||||
|
|
||||||
/*1: Enable API to take snapshot for object*/
|
|
||||||
#define LV_USE_SNAPSHOT 0
|
|
||||||
|
|
||||||
/*1: Enable Monkey test*/
|
|
||||||
#define LV_USE_MONKEY 0
|
|
||||||
|
|
||||||
/*1: Enable grid navigation*/
|
|
||||||
#define LV_USE_GRIDNAV 0
|
|
||||||
|
|
||||||
/*1: Enable lv_obj fragment*/
|
|
||||||
#define LV_USE_FRAGMENT 0
|
|
||||||
|
|
||||||
/*1: Support using images as font in label or span widgets */
|
|
||||||
#define LV_USE_IMGFONT 0
|
|
||||||
|
|
||||||
/*1: Enable a published subscriber based messaging system */
|
|
||||||
#define LV_USE_MSG 0
|
|
||||||
|
|
||||||
/*1: Enable Pinyin input method*/
|
|
||||||
/*Requires: lv_keyboard*/
|
|
||||||
#define LV_USE_IME_PINYIN 0
|
|
||||||
#if LV_USE_IME_PINYIN
|
|
||||||
/*1: Use default thesaurus*/
|
|
||||||
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
|
|
||||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
|
|
||||||
/*Set the maximum number of candidate panels that can be displayed*/
|
|
||||||
/*This needs to be adjusted according to the size of the screen*/
|
|
||||||
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
|
|
||||||
|
|
||||||
/*Use 9 key input(k9)*/
|
|
||||||
#define LV_IME_PINYIN_USE_K9_MODE 1
|
|
||||||
#if LV_IME_PINYIN_USE_K9_MODE == 1
|
|
||||||
#define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
|
|
||||||
#endif // LV_IME_PINYIN_USE_K9_MODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*==================
|
|
||||||
* EXAMPLES
|
|
||||||
*==================*/
|
|
||||||
|
|
||||||
/*Enable the examples to be built with the library*/
|
|
||||||
#define LV_BUILD_EXAMPLES 1
|
|
||||||
|
|
||||||
/*===================
|
|
||||||
* DEMO USAGE
|
|
||||||
====================*/
|
|
||||||
|
|
||||||
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
|
|
||||||
#define LV_USE_DEMO_WIDGETS 0
|
|
||||||
#if LV_USE_DEMO_WIDGETS
|
|
||||||
#define LV_DEMO_WIDGETS_SLIDESHOW 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Demonstrate the usage of encoder and keyboard*/
|
|
||||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
|
||||||
|
|
||||||
/*Benchmark your system*/
|
|
||||||
#define LV_USE_DEMO_BENCHMARK 0
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
|
||||||
/*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/
|
|
||||||
#define LV_DEMO_BENCHMARK_RGB565A8 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Stress test for LVGL*/
|
|
||||||
#define LV_USE_DEMO_STRESS 0
|
|
||||||
|
|
||||||
/*Music player demo*/
|
|
||||||
#define LV_USE_DEMO_MUSIC 0
|
|
||||||
#if LV_USE_DEMO_MUSIC
|
|
||||||
#define LV_DEMO_MUSIC_SQUARE 0
|
|
||||||
#define LV_DEMO_MUSIC_LANDSCAPE 0
|
|
||||||
#define LV_DEMO_MUSIC_ROUND 0
|
|
||||||
#define LV_DEMO_MUSIC_LARGE 0
|
|
||||||
#define LV_DEMO_MUSIC_AUTO_PLAY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*--END OF LV_CONF_H--*/
|
|
||||||
|
|
||||||
#endif /*LV_CONF_H*/
|
|
||||||
|
|
||||||
#endif /*End of "Content enable"*/
|
|
@ -1,138 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lvgl.h
|
|
||||||
* Include all LVGL related headers
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LVGL_H
|
|
||||||
#define LVGL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************
|
|
||||||
* CURRENT VERSION OF LVGL
|
|
||||||
***************************/
|
|
||||||
#define LVGL_VERSION_MAJOR 8
|
|
||||||
#define LVGL_VERSION_MINOR 3
|
|
||||||
#define LVGL_VERSION_PATCH 1
|
|
||||||
#define LVGL_VERSION_INFO ""
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#include "src/misc/lv_log.h"
|
|
||||||
#include "src/misc/lv_timer.h"
|
|
||||||
#include "src/misc/lv_math.h"
|
|
||||||
#include "src/misc/lv_mem.h"
|
|
||||||
#include "src/misc/lv_async.h"
|
|
||||||
#include "src/misc/lv_anim_timeline.h"
|
|
||||||
#include "src/misc/lv_printf.h"
|
|
||||||
|
|
||||||
#include "src/hal/lv_hal.h"
|
|
||||||
|
|
||||||
#include "src/core/lv_obj.h"
|
|
||||||
#include "src/core/lv_group.h"
|
|
||||||
#include "src/core/lv_indev.h"
|
|
||||||
#include "src/core/lv_refr.h"
|
|
||||||
#include "src/core/lv_disp.h"
|
|
||||||
#include "src/core/lv_theme.h"
|
|
||||||
|
|
||||||
#include "src/font/lv_font.h"
|
|
||||||
#include "src/font/lv_font_loader.h"
|
|
||||||
#include "src/font/lv_font_fmt_txt.h"
|
|
||||||
|
|
||||||
#include "src/widgets/lv_arc.h"
|
|
||||||
#include "src/widgets/lv_btn.h"
|
|
||||||
#include "src/widgets/lv_img.h"
|
|
||||||
#include "src/widgets/lv_label.h"
|
|
||||||
#include "src/widgets/lv_line.h"
|
|
||||||
#include "src/widgets/lv_table.h"
|
|
||||||
#include "src/widgets/lv_checkbox.h"
|
|
||||||
#include "src/widgets/lv_bar.h"
|
|
||||||
#include "src/widgets/lv_slider.h"
|
|
||||||
#include "src/widgets/lv_btnmatrix.h"
|
|
||||||
#include "src/widgets/lv_dropdown.h"
|
|
||||||
#include "src/widgets/lv_roller.h"
|
|
||||||
#include "src/widgets/lv_textarea.h"
|
|
||||||
#include "src/widgets/lv_canvas.h"
|
|
||||||
#include "src/widgets/lv_switch.h"
|
|
||||||
|
|
||||||
#include "src/draw/lv_draw.h"
|
|
||||||
|
|
||||||
#include "src/lv_api_map.h"
|
|
||||||
|
|
||||||
/*-----------------
|
|
||||||
* EXTRAS
|
|
||||||
*----------------*/
|
|
||||||
#include "src/extra/lv_extra.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/** Gives 1 if the x.y.z version is supported in the current version
|
|
||||||
* Usage:
|
|
||||||
*
|
|
||||||
* - Require v6
|
|
||||||
* #if LV_VERSION_CHECK(6,0,0)
|
|
||||||
* new_func_in_v6();
|
|
||||||
* #endif
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* - Require at least v5.3
|
|
||||||
* #if LV_VERSION_CHECK(5,3,0)
|
|
||||||
* new_feature_from_v5_3();
|
|
||||||
* #endif
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* - Require v5.3.2 bugfixes
|
|
||||||
* #if LV_VERSION_CHECK(5,3,2)
|
|
||||||
* bugfix_in_v5_3_2();
|
|
||||||
* #endif
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH)))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper functions for VERSION macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline int lv_version_major(void)
|
|
||||||
{
|
|
||||||
return LVGL_VERSION_MAJOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lv_version_minor(void)
|
|
||||||
{
|
|
||||||
return LVGL_VERSION_MINOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lv_version_patch(void)
|
|
||||||
{
|
|
||||||
return LVGL_VERSION_PATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char *lv_version_info(void)
|
|
||||||
{
|
|
||||||
return LVGL_VERSION_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LVGL_H*/
|
|
@ -1,9 +0,0 @@
|
|||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/demos/lv_demos.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/lv_examples.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra/lv_extra.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font/lv_font.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal/lv_hal.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc/lv_misc.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets/lv_widgets.mk
|
|
@ -1,20 +0,0 @@
|
|||||||
CSRCS += lv_disp.c
|
|
||||||
CSRCS += lv_group.c
|
|
||||||
CSRCS += lv_indev.c
|
|
||||||
CSRCS += lv_indev_scroll.c
|
|
||||||
CSRCS += lv_obj.c
|
|
||||||
CSRCS += lv_obj_class.c
|
|
||||||
CSRCS += lv_obj_draw.c
|
|
||||||
CSRCS += lv_obj_pos.c
|
|
||||||
CSRCS += lv_obj_scroll.c
|
|
||||||
CSRCS += lv_obj_style.c
|
|
||||||
CSRCS += lv_obj_style_gen.c
|
|
||||||
CSRCS += lv_obj_tree.c
|
|
||||||
CSRCS += lv_event.c
|
|
||||||
CSRCS += lv_refr.c
|
|
||||||
CSRCS += lv_theme.c
|
|
||||||
|
|
||||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core
|
|
||||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core
|
|
||||||
|
|
||||||
CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core"
|
|
@ -1,534 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_disp.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_disp.h"
|
|
||||||
#include "../misc/lv_math.h"
|
|
||||||
#include "../core/lv_refr.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void scr_load_internal(lv_obj_t * scr);
|
|
||||||
static void scr_load_anim_start(lv_anim_t * a);
|
|
||||||
static void opa_scale_anim(void * obj, int32_t v);
|
|
||||||
static void set_x_anim(void * obj, int32_t v);
|
|
||||||
static void set_y_anim(void * obj, int32_t v);
|
|
||||||
static void scr_anim_ready(lv_anim_t * a);
|
|
||||||
static bool is_out_anim(lv_scr_load_anim_t a);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with a pointer to the active screen
|
|
||||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
|
||||||
* screen)
|
|
||||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered to get its active screen");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return disp->act_scr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
|
||||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
|
||||||
* screen)
|
|
||||||
* @return pointer to the previous screen object or NULL if not used now
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered to get its previous screen");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return disp->prev_scr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a screen active
|
|
||||||
* @param scr pointer to a screen
|
|
||||||
*/
|
|
||||||
void lv_disp_load_scr(lv_obj_t * scr)
|
|
||||||
{
|
|
||||||
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
|
||||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
|
||||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return disp->top_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
|
||||||
* layer)
|
|
||||||
* @param disp pointer to display which sys. layer should be retrieved. (NULL to use the default screen)
|
|
||||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("lv_layer_sys: no display registered to get its sys. layer");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return disp->sys_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the theme of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
*/
|
|
||||||
void lv_disp_set_theme(lv_disp_t * disp, lv_theme_t * th)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->theme = th;
|
|
||||||
|
|
||||||
if(disp->screen_cnt == 3 &&
|
|
||||||
lv_obj_get_child_cnt(disp->screens[0]) == 0 &&
|
|
||||||
lv_obj_get_child_cnt(disp->screens[1]) == 0 &&
|
|
||||||
lv_obj_get_child_cnt(disp->screens[2]) == 0) {
|
|
||||||
lv_theme_apply(disp->screens[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Get the theme of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @return the display's theme (can be NULL)
|
|
||||||
*/
|
|
||||||
lv_theme_t * lv_disp_get_theme(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(disp == NULL) disp = lv_disp_get_default();
|
|
||||||
return disp->theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the background color of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param color color of the background
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->bg_color = color;
|
|
||||||
|
|
||||||
lv_area_t a;
|
|
||||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
|
||||||
_lv_inv_area(disp, &a);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the background image of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->bg_img = img_src;
|
|
||||||
|
|
||||||
lv_area_t a;
|
|
||||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
|
||||||
_lv_inv_area(disp, &a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set opacity of the background
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param opa opacity (0..255)
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->bg_opa = opa;
|
|
||||||
|
|
||||||
lv_area_t a;
|
|
||||||
lv_area_set(&a, 0, 0, lv_disp_get_hor_res(disp) - 1, lv_disp_get_ver_res(disp) - 1);
|
|
||||||
_lv_inv_area(disp, &a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Switch screen with animation
|
|
||||||
* @param scr pointer to the new screen to load
|
|
||||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
|
||||||
* @param time time of the animation
|
|
||||||
* @param delay delay before the transition
|
|
||||||
* @param auto_del true: automatically delete the old screen
|
|
||||||
*/
|
|
||||||
void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del)
|
|
||||||
{
|
|
||||||
|
|
||||||
lv_disp_t * d = lv_obj_get_disp(new_scr);
|
|
||||||
lv_obj_t * act_scr = lv_scr_act();
|
|
||||||
|
|
||||||
/*If an other screen load animation is in progress
|
|
||||||
*make target screen loaded immediately. */
|
|
||||||
if(d->scr_to_load && act_scr != d->scr_to_load) {
|
|
||||||
scr_load_internal(d->scr_to_load);
|
|
||||||
lv_anim_del(d->scr_to_load, NULL);
|
|
||||||
lv_obj_set_pos(d->scr_to_load, 0, 0);
|
|
||||||
lv_obj_remove_local_style_prop(d->scr_to_load, LV_STYLE_OPA, 0);
|
|
||||||
|
|
||||||
if(d->del_prev) {
|
|
||||||
lv_obj_del(act_scr);
|
|
||||||
}
|
|
||||||
act_scr = d->scr_to_load;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->scr_to_load = new_scr;
|
|
||||||
|
|
||||||
if(d->prev_scr && d->del_prev) {
|
|
||||||
lv_obj_del(d->prev_scr);
|
|
||||||
d->prev_scr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->draw_prev_over_act = is_out_anim(anim_type);
|
|
||||||
d->del_prev = auto_del;
|
|
||||||
|
|
||||||
/*Be sure there is no other animation on the screens*/
|
|
||||||
lv_anim_del(new_scr, NULL);
|
|
||||||
lv_anim_del(lv_scr_act(), NULL);
|
|
||||||
|
|
||||||
/*Be sure both screens are in a normal position*/
|
|
||||||
lv_obj_set_pos(new_scr, 0, 0);
|
|
||||||
lv_obj_set_pos(lv_scr_act(), 0, 0);
|
|
||||||
lv_obj_remove_local_style_prop(new_scr, LV_STYLE_OPA, 0);
|
|
||||||
lv_obj_remove_local_style_prop(lv_scr_act(), LV_STYLE_OPA, 0);
|
|
||||||
|
|
||||||
|
|
||||||
/*Shortcut for immediate load*/
|
|
||||||
if(time == 0 && delay == 0) {
|
|
||||||
scr_load_internal(new_scr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_anim_t a_new;
|
|
||||||
lv_anim_init(&a_new);
|
|
||||||
lv_anim_set_var(&a_new, new_scr);
|
|
||||||
lv_anim_set_start_cb(&a_new, scr_load_anim_start);
|
|
||||||
lv_anim_set_ready_cb(&a_new, scr_anim_ready);
|
|
||||||
lv_anim_set_time(&a_new, time);
|
|
||||||
lv_anim_set_delay(&a_new, delay);
|
|
||||||
|
|
||||||
lv_anim_t a_old;
|
|
||||||
lv_anim_init(&a_old);
|
|
||||||
lv_anim_set_var(&a_old, d->act_scr);
|
|
||||||
lv_anim_set_time(&a_old, time);
|
|
||||||
lv_anim_set_delay(&a_old, delay);
|
|
||||||
|
|
||||||
switch(anim_type) {
|
|
||||||
case LV_SCR_LOAD_ANIM_NONE:
|
|
||||||
/*Create a dummy animation to apply the delay*/
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_new, 0, 0);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OVER_LEFT:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OVER_RIGHT:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OVER_TOP:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OVER_BOTTOM:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_MOVE_LEFT:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_new, lv_disp_get_hor_res(d), 0);
|
|
||||||
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_MOVE_RIGHT:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_new, -lv_disp_get_hor_res(d), 0);
|
|
||||||
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_MOVE_TOP:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_new, lv_disp_get_ver_res(d), 0);
|
|
||||||
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_MOVE_BOTTOM:
|
|
||||||
lv_anim_set_exec_cb(&a_new, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_new, -lv_disp_get_ver_res(d), 0);
|
|
||||||
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_FADE_IN:
|
|
||||||
lv_anim_set_exec_cb(&a_new, opa_scale_anim);
|
|
||||||
lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_FADE_OUT:
|
|
||||||
lv_anim_set_exec_cb(&a_old, opa_scale_anim);
|
|
||||||
lv_anim_set_values(&a_old, LV_OPA_COVER, LV_OPA_TRANSP);
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OUT_LEFT:
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OUT_RIGHT:
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_x_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OUT_TOP:
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d));
|
|
||||||
break;
|
|
||||||
case LV_SCR_LOAD_ANIM_OUT_BOTTOM:
|
|
||||||
lv_anim_set_exec_cb(&a_old, set_y_anim);
|
|
||||||
lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_event_send(act_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
|
|
||||||
|
|
||||||
lv_anim_start(&a_new);
|
|
||||||
lv_anim_start(&a_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get elapsed time since last user activity on a display (e.g. click)
|
|
||||||
* @param disp pointer to a display (NULL to get the overall smallest inactivity)
|
|
||||||
* @return elapsed ticks (milliseconds) since the last activity
|
|
||||||
*/
|
|
||||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(disp) return lv_tick_elaps(disp->last_activity_time);
|
|
||||||
|
|
||||||
lv_disp_t * d;
|
|
||||||
uint32_t t = UINT32_MAX;
|
|
||||||
d = lv_disp_get_next(NULL);
|
|
||||||
while(d) {
|
|
||||||
uint32_t elaps = lv_tick_elaps(d->last_activity_time);
|
|
||||||
t = LV_MIN(t, elaps);
|
|
||||||
d = lv_disp_get_next(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manually trigger an activity on a display
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
*/
|
|
||||||
void lv_disp_trig_activity(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("lv_disp_trig_activity: no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->last_activity_time = lv_tick_get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean any CPU cache that is related to the display.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
*/
|
|
||||||
void lv_disp_clean_dcache(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("lv_disp_clean_dcache: no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(disp->driver->clean_dcache_cb)
|
|
||||||
disp->driver->clean_dcache_cb(disp->driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily enable and disable the invalidation of the display.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
* @param en true: enable invalidation; false: invalidation
|
|
||||||
*/
|
|
||||||
void lv_disp_enable_invalidation(lv_disp_t * disp, bool en)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp->inv_en_cnt += en ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get display invalidation is enabled.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
* @return return true if invalidation is enabled
|
|
||||||
*/
|
|
||||||
bool lv_disp_is_invalidation_enabled(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("no display registered");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (disp->inv_en_cnt > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to the screen refresher timer to
|
|
||||||
* modify its parameters with `lv_timer_...` functions.
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @return pointer to the display refresher timer. (NULL on error)
|
|
||||||
*/
|
|
||||||
lv_timer_t * _lv_disp_get_refr_timer(lv_disp_t * disp)
|
|
||||||
{
|
|
||||||
if(!disp) disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("lv_disp_get_refr_timer: no display registered");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return disp->refr_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void scr_load_internal(lv_obj_t * scr)
|
|
||||||
{
|
|
||||||
lv_disp_t * d = lv_obj_get_disp(scr);
|
|
||||||
if(!d) return; /*Shouldn't happen, just to be sure*/
|
|
||||||
|
|
||||||
lv_obj_t * old_scr = d->act_scr;
|
|
||||||
|
|
||||||
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
|
|
||||||
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOAD_START, NULL);
|
|
||||||
|
|
||||||
d->act_scr = scr;
|
|
||||||
|
|
||||||
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOADED, NULL);
|
|
||||||
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
|
|
||||||
|
|
||||||
lv_obj_invalidate(scr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scr_load_anim_start(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
|
||||||
|
|
||||||
d->prev_scr = lv_scr_act();
|
|
||||||
d->act_scr = a->var;
|
|
||||||
|
|
||||||
lv_event_send(d->act_scr, LV_EVENT_SCREEN_LOAD_START, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void opa_scale_anim(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_opa(obj, v, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_x_anim(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
lv_obj_set_x(obj, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_y_anim(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
lv_obj_set_y(obj, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scr_anim_ready(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
lv_disp_t * d = lv_obj_get_disp(a->var);
|
|
||||||
|
|
||||||
lv_event_send(d->act_scr, LV_EVENT_SCREEN_LOADED, NULL);
|
|
||||||
lv_event_send(d->prev_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
|
|
||||||
|
|
||||||
if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr);
|
|
||||||
d->prev_scr = NULL;
|
|
||||||
d->draw_prev_over_act = false;
|
|
||||||
d->scr_to_load = NULL;
|
|
||||||
lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0);
|
|
||||||
lv_obj_invalidate(d->act_scr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_out_anim(lv_scr_load_anim_t anim_type)
|
|
||||||
{
|
|
||||||
return anim_type == LV_SCR_LOAD_ANIM_FADE_OUT ||
|
|
||||||
anim_type == LV_SCR_LOAD_ANIM_OUT_LEFT ||
|
|
||||||
anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT ||
|
|
||||||
anim_type == LV_SCR_LOAD_ANIM_OUT_TOP ||
|
|
||||||
anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM;
|
|
||||||
}
|
|
@ -1,264 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_disp.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_DISP_H
|
|
||||||
#define LV_DISP_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../hal/lv_hal.h"
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_theme.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_SCR_LOAD_ANIM_NONE,
|
|
||||||
LV_SCR_LOAD_ANIM_OVER_LEFT,
|
|
||||||
LV_SCR_LOAD_ANIM_OVER_RIGHT,
|
|
||||||
LV_SCR_LOAD_ANIM_OVER_TOP,
|
|
||||||
LV_SCR_LOAD_ANIM_OVER_BOTTOM,
|
|
||||||
LV_SCR_LOAD_ANIM_MOVE_LEFT,
|
|
||||||
LV_SCR_LOAD_ANIM_MOVE_RIGHT,
|
|
||||||
LV_SCR_LOAD_ANIM_MOVE_TOP,
|
|
||||||
LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
|
|
||||||
LV_SCR_LOAD_ANIM_FADE_IN,
|
|
||||||
LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/
|
|
||||||
LV_SCR_LOAD_ANIM_FADE_OUT,
|
|
||||||
LV_SCR_LOAD_ANIM_OUT_LEFT,
|
|
||||||
LV_SCR_LOAD_ANIM_OUT_RIGHT,
|
|
||||||
LV_SCR_LOAD_ANIM_OUT_TOP,
|
|
||||||
LV_SCR_LOAD_ANIM_OUT_BOTTOM,
|
|
||||||
} lv_scr_load_anim_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with a pointer to the active screen
|
|
||||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
|
||||||
* screen)
|
|
||||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
|
||||||
* @param disp pointer to display which previous screen should be get. (NULL to use the default
|
|
||||||
* screen)
|
|
||||||
* @return pointer to the previous screen object or NULL if not used now
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a screen active
|
|
||||||
* @param scr pointer to a screen
|
|
||||||
*/
|
|
||||||
void lv_disp_load_scr(lv_obj_t * scr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
|
||||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
|
||||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
|
||||||
* layer)
|
|
||||||
* @param disp pointer to display which sys. layer should be retrieved. (NULL to use the default screen)
|
|
||||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the theme of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
*/
|
|
||||||
void lv_disp_set_theme(lv_disp_t * disp, lv_theme_t * th);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the theme of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @return the display's theme (can be NULL)
|
|
||||||
*/
|
|
||||||
lv_theme_t * lv_disp_get_theme(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the background color of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param color color of the background
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_color(lv_disp_t * disp, lv_color_t color);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the background image of a display
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param img_src path to file or pointer to an `lv_img_dsc_t` variable
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_image(lv_disp_t * disp, const void * img_src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set opacity of the background
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @param opa opacity (0..255)
|
|
||||||
*/
|
|
||||||
void lv_disp_set_bg_opa(lv_disp_t * disp, lv_opa_t opa);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Switch screen with animation
|
|
||||||
* @param scr pointer to the new screen to load
|
|
||||||
* @param anim_type type of the animation from `lv_scr_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
|
||||||
* @param time time of the animation
|
|
||||||
* @param delay delay before the transition
|
|
||||||
* @param auto_del true: automatically delete the old screen
|
|
||||||
*/
|
|
||||||
void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get elapsed time since last user activity on a display (e.g. click)
|
|
||||||
* @param disp pointer to a display (NULL to get the overall smallest inactivity)
|
|
||||||
* @return elapsed ticks (milliseconds) since the last activity
|
|
||||||
*/
|
|
||||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manually trigger an activity on a display
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
*/
|
|
||||||
void lv_disp_trig_activity(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean any CPU cache that is related to the display.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
*/
|
|
||||||
void lv_disp_clean_dcache(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily enable and disable the invalidation of the display.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
* @param en true: enable invalidation; false: invalidation
|
|
||||||
*/
|
|
||||||
void lv_disp_enable_invalidation(lv_disp_t * disp, bool en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get display invalidation is enabled.
|
|
||||||
* @param disp pointer to a display (NULL to use the default display)
|
|
||||||
* @return return true if invalidation is enabled
|
|
||||||
*/
|
|
||||||
bool lv_disp_is_invalidation_enabled(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to the screen refresher timer to
|
|
||||||
* modify its parameters with `lv_timer_...` functions.
|
|
||||||
* @param disp pointer to a display
|
|
||||||
* @return pointer to the display refresher timer. (NULL on error)
|
|
||||||
*/
|
|
||||||
lv_timer_t * _lv_disp_get_refr_timer(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/*------------------------------------------------
|
|
||||||
* To improve backward compatibility
|
|
||||||
* Recommended only if you have one display
|
|
||||||
*------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the active screen of the default display
|
|
||||||
* @return pointer to the active screen
|
|
||||||
*/
|
|
||||||
static inline lv_obj_t * lv_scr_act(void)
|
|
||||||
{
|
|
||||||
return lv_disp_get_scr_act(lv_disp_get_default());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top layer of the default display
|
|
||||||
* @return pointer to the top layer
|
|
||||||
*/
|
|
||||||
static inline lv_obj_t * lv_layer_top(void)
|
|
||||||
{
|
|
||||||
return lv_disp_get_layer_top(lv_disp_get_default());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the active screen of the default display
|
|
||||||
* @return pointer to the sys layer
|
|
||||||
*/
|
|
||||||
static inline lv_obj_t * lv_layer_sys(void)
|
|
||||||
{
|
|
||||||
return lv_disp_get_layer_sys(lv_disp_get_default());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lv_scr_load(lv_obj_t * scr)
|
|
||||||
{
|
|
||||||
lv_disp_load_scr(scr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*------------------------------------------------
|
|
||||||
* To improve backward compatibility
|
|
||||||
* Recommended only if you have one display
|
|
||||||
*------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef LV_HOR_RES
|
|
||||||
/**
|
|
||||||
* The horizontal resolution of the currently active display.
|
|
||||||
*/
|
|
||||||
#define LV_HOR_RES lv_disp_get_hor_res(lv_disp_get_default())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LV_VER_RES
|
|
||||||
/**
|
|
||||||
* The vertical resolution of the currently active display.
|
|
||||||
*/
|
|
||||||
#define LV_VER_RES lv_disp_get_ver_res(lv_disp_get_default())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale the given number of pixels (a distance or size) relative to a 160 DPI display
|
|
||||||
* considering the DPI of the default display.
|
|
||||||
* It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
|
|
||||||
* DPI of the display.
|
|
||||||
* @param n the number of pixels to scale
|
|
||||||
* @return `n x current_dpi/160`
|
|
||||||
*/
|
|
||||||
static inline lv_coord_t lv_dpx(lv_coord_t n)
|
|
||||||
{
|
|
||||||
return LV_DPX(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale the given number of pixels (a distance or size) relative to a 160 DPI display
|
|
||||||
* considering the DPI of the given display.
|
|
||||||
* It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
|
|
||||||
* DPI of the display.
|
|
||||||
* @param obj a display whose dpi should be considered
|
|
||||||
* @param n the number of pixels to scale
|
|
||||||
* @return `n x current_dpi/160`
|
|
||||||
*/
|
|
||||||
static inline lv_coord_t lv_disp_dpx(const lv_disp_t * disp, lv_coord_t n)
|
|
||||||
{
|
|
||||||
return _LV_DPX_CALC(lv_disp_get_dpi(disp), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_DISP_H*/
|
|
@ -1,527 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_event.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_indev.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
typedef struct _lv_event_dsc_t {
|
|
||||||
lv_event_cb_t cb;
|
|
||||||
void * user_data;
|
|
||||||
lv_event_code_t filter : 8;
|
|
||||||
} lv_event_dsc_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static lv_event_dsc_t * lv_obj_get_event_dsc(const lv_obj_t * obj, uint32_t id);
|
|
||||||
static lv_res_t event_send_core(lv_event_t * e);
|
|
||||||
static bool event_is_bubbled(lv_event_t * e);
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static lv_event_t * event_head;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
#if LV_LOG_TRACE_EVENT
|
|
||||||
#define EVENT_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define EVENT_TRACE(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param)
|
|
||||||
{
|
|
||||||
if(obj == NULL) return LV_RES_OK;
|
|
||||||
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_event_t e;
|
|
||||||
e.target = obj;
|
|
||||||
e.current_target = obj;
|
|
||||||
e.code = event_code;
|
|
||||||
e.user_data = NULL;
|
|
||||||
e.param = param;
|
|
||||||
e.deleted = 0;
|
|
||||||
e.stop_bubbling = 0;
|
|
||||||
e.stop_processing = 0;
|
|
||||||
|
|
||||||
/*Build a simple linked list from the objects used in the events
|
|
||||||
*It's important to know if this object was deleted by a nested event
|
|
||||||
*called from this `event_cb`.*/
|
|
||||||
e.prev = event_head;
|
|
||||||
event_head = &e;
|
|
||||||
|
|
||||||
/*Send the event*/
|
|
||||||
lv_res_t res = event_send_core(&e);
|
|
||||||
|
|
||||||
/*Remove this element from the list*/
|
|
||||||
event_head = e.prev;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
|
|
||||||
{
|
|
||||||
const lv_obj_class_t * base;
|
|
||||||
if(class_p == NULL) base = e->current_target->class_p;
|
|
||||||
else base = class_p->base_class;
|
|
||||||
|
|
||||||
/*Find a base in which call the ancestor's event handler_cb if set*/
|
|
||||||
while(base && base->event_cb == NULL) base = base->base_class;
|
|
||||||
|
|
||||||
if(base == NULL) return LV_RES_OK;
|
|
||||||
if(base->event_cb == NULL) return LV_RES_OK;
|
|
||||||
|
|
||||||
/*Call the actual event callback*/
|
|
||||||
e->user_data = NULL;
|
|
||||||
base->event_cb(base, e);
|
|
||||||
|
|
||||||
lv_res_t res = LV_RES_OK;
|
|
||||||
/*Stop if the object is deleted*/
|
|
||||||
if(e->deleted) res = LV_RES_INV;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lv_obj_t * lv_event_get_target(lv_event_t * e)
|
|
||||||
{
|
|
||||||
return e->target;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * lv_event_get_current_target(lv_event_t * e)
|
|
||||||
{
|
|
||||||
return e->current_target;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_event_code_t lv_event_get_code(lv_event_t * e)
|
|
||||||
{
|
|
||||||
return e->code & ~LV_EVENT_PREPROCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * lv_event_get_param(lv_event_t * e)
|
|
||||||
{
|
|
||||||
return e->param;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * lv_event_get_user_data(lv_event_t * e)
|
|
||||||
{
|
|
||||||
return e->user_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_event_stop_bubbling(lv_event_t * e)
|
|
||||||
{
|
|
||||||
e->stop_bubbling = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_event_stop_processing(lv_event_t * e)
|
|
||||||
{
|
|
||||||
e->stop_processing = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t lv_event_register_id(void)
|
|
||||||
{
|
|
||||||
static uint32_t last_id = _LV_EVENT_LAST;
|
|
||||||
last_id ++;
|
|
||||||
return last_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _lv_event_mark_deleted(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_event_t * e = event_head;
|
|
||||||
|
|
||||||
while(e) {
|
|
||||||
if(e->current_target == obj || e->target == obj) e->deleted = 1;
|
|
||||||
e = e->prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct _lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,
|
|
||||||
void * user_data)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
|
|
||||||
obj->spec_attr->event_dsc_cnt++;
|
|
||||||
obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
|
|
||||||
obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
|
|
||||||
|
|
||||||
obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].cb = event_cb;
|
|
||||||
obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].filter = filter;
|
|
||||||
obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].user_data = user_data;
|
|
||||||
|
|
||||||
return &obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
if(obj->spec_attr == NULL) return false;
|
|
||||||
|
|
||||||
int32_t i = 0;
|
|
||||||
for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
|
|
||||||
if(event_cb == NULL || obj->spec_attr->event_dsc[i].cb == event_cb) {
|
|
||||||
/*Shift the remaining event handlers forward*/
|
|
||||||
for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
|
|
||||||
obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
|
|
||||||
}
|
|
||||||
obj->spec_attr->event_dsc_cnt--;
|
|
||||||
obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
|
|
||||||
obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*No event handler found*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, const void * user_data)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
if(obj->spec_attr == NULL) return false;
|
|
||||||
|
|
||||||
int32_t i = 0;
|
|
||||||
for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
|
|
||||||
if((event_cb == NULL || obj->spec_attr->event_dsc[i].cb == event_cb) &&
|
|
||||||
obj->spec_attr->event_dsc[i].user_data == user_data) {
|
|
||||||
/*Shift the remaining event handlers forward*/
|
|
||||||
for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
|
|
||||||
obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
|
|
||||||
}
|
|
||||||
obj->spec_attr->event_dsc_cnt--;
|
|
||||||
obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
|
|
||||||
obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*No event handler found*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool lv_obj_remove_event_dsc(lv_obj_t * obj, struct _lv_event_dsc_t * event_dsc)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
if(obj->spec_attr == NULL) return false;
|
|
||||||
|
|
||||||
int32_t i = 0;
|
|
||||||
for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
|
|
||||||
if(&obj->spec_attr->event_dsc[i] == event_dsc) {
|
|
||||||
/*Shift the remaining event handlers forward*/
|
|
||||||
for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
|
|
||||||
obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
|
|
||||||
}
|
|
||||||
obj->spec_attr->event_dsc_cnt--;
|
|
||||||
obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
|
|
||||||
obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*No event handler found*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * lv_obj_get_event_user_data(struct _lv_obj_t * obj, lv_event_cb_t event_cb)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
if(obj->spec_attr == NULL) return NULL;
|
|
||||||
|
|
||||||
int32_t i = 0;
|
|
||||||
for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
|
|
||||||
if(event_cb == obj->spec_attr->event_dsc[i].cb) return obj->spec_attr->event_dsc[i].user_data;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_indev_t * lv_event_get_indev(lv_event_t * e)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(e->code == LV_EVENT_PRESSED ||
|
|
||||||
e->code == LV_EVENT_PRESSING ||
|
|
||||||
e->code == LV_EVENT_PRESS_LOST ||
|
|
||||||
e->code == LV_EVENT_SHORT_CLICKED ||
|
|
||||||
e->code == LV_EVENT_LONG_PRESSED ||
|
|
||||||
e->code == LV_EVENT_LONG_PRESSED_REPEAT ||
|
|
||||||
e->code == LV_EVENT_CLICKED ||
|
|
||||||
e->code == LV_EVENT_RELEASED ||
|
|
||||||
e->code == LV_EVENT_SCROLL_BEGIN ||
|
|
||||||
e->code == LV_EVENT_SCROLL_END ||
|
|
||||||
e->code == LV_EVENT_SCROLL ||
|
|
||||||
e->code == LV_EVENT_GESTURE ||
|
|
||||||
e->code == LV_EVENT_KEY ||
|
|
||||||
e->code == LV_EVENT_FOCUSED ||
|
|
||||||
e->code == LV_EVENT_DEFOCUSED ||
|
|
||||||
e->code == LV_EVENT_LEAVE) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_draw_part_dsc_t * lv_event_get_draw_part_dsc(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_DRAW_PART_BEGIN ||
|
|
||||||
e->code == LV_EVENT_DRAW_PART_END) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_draw_ctx_t * lv_event_get_draw_ctx(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_DRAW_MAIN ||
|
|
||||||
e->code == LV_EVENT_DRAW_MAIN_BEGIN ||
|
|
||||||
e->code == LV_EVENT_DRAW_MAIN_END ||
|
|
||||||
e->code == LV_EVENT_DRAW_POST ||
|
|
||||||
e->code == LV_EVENT_DRAW_POST_BEGIN ||
|
|
||||||
e->code == LV_EVENT_DRAW_POST_END) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_area_t * lv_event_get_old_size(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_SIZE_CHANGED) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lv_event_get_key(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_KEY) {
|
|
||||||
uint32_t * k = lv_event_get_param(e);
|
|
||||||
if(k) return *k;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_SCROLL_BEGIN) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
|
|
||||||
lv_coord_t * cur_size = lv_event_get_param(e);
|
|
||||||
*cur_size = LV_MAX(*cur_size, size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_point_t * lv_event_get_self_size_info(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_GET_SELF_SIZE) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_HIT_TEST) {
|
|
||||||
return lv_event_get_param(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_area_t * lv_event_get_cover_area(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_COVER_CHECK) {
|
|
||||||
lv_cover_check_info_t * p = lv_event_get_param(e);
|
|
||||||
return p->area;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res)
|
|
||||||
{
|
|
||||||
if(e->code == LV_EVENT_COVER_CHECK) {
|
|
||||||
lv_cover_check_info_t * p = lv_event_get_param(e);
|
|
||||||
if(res > p->res) p->res = res; /*Save only "stronger" results*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static lv_event_dsc_t * lv_obj_get_event_dsc(const lv_obj_t * obj, uint32_t id)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(!obj->spec_attr) return NULL;
|
|
||||||
if(id >= obj->spec_attr->event_dsc_cnt) return NULL;
|
|
||||||
|
|
||||||
return &obj->spec_attr->event_dsc[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
static lv_res_t event_send_core(lv_event_t * e)
|
|
||||||
{
|
|
||||||
EVENT_TRACE("Sending event %d to %p with %p param", e->code, (void *)e->current_target, e->param);
|
|
||||||
|
|
||||||
/*Call the input device's feedback callback if set*/
|
|
||||||
lv_indev_t * indev_act = lv_indev_get_act();
|
|
||||||
if(indev_act) {
|
|
||||||
if(indev_act->driver->feedback_cb) indev_act->driver->feedback_cb(indev_act->driver, e->code);
|
|
||||||
if(e->stop_processing) return LV_RES_OK;
|
|
||||||
if(e->deleted) return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_res_t res = LV_RES_OK;
|
|
||||||
lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(e->current_target, 0);
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
while(event_dsc && res == LV_RES_OK) {
|
|
||||||
if(event_dsc->cb && ((event_dsc->filter & LV_EVENT_PREPROCESS) == LV_EVENT_PREPROCESS)
|
|
||||||
&& (event_dsc->filter == (LV_EVENT_ALL | LV_EVENT_PREPROCESS) ||
|
|
||||||
(event_dsc->filter & ~LV_EVENT_PREPROCESS) == e->code)) {
|
|
||||||
e->user_data = event_dsc->user_data;
|
|
||||||
event_dsc->cb(e);
|
|
||||||
|
|
||||||
if(e->stop_processing) return LV_RES_OK;
|
|
||||||
/*Stop if the object is deleted*/
|
|
||||||
if(e->deleted) return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
event_dsc = lv_obj_get_event_dsc(e->current_target, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
res = lv_obj_event_base(NULL, e);
|
|
||||||
|
|
||||||
event_dsc = res == LV_RES_INV ? NULL : lv_obj_get_event_dsc(e->current_target, 0);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while(event_dsc && res == LV_RES_OK) {
|
|
||||||
if(event_dsc->cb && ((event_dsc->filter & LV_EVENT_PREPROCESS) == 0)
|
|
||||||
&& (event_dsc->filter == LV_EVENT_ALL || event_dsc->filter == e->code)) {
|
|
||||||
e->user_data = event_dsc->user_data;
|
|
||||||
event_dsc->cb(e);
|
|
||||||
|
|
||||||
if(e->stop_processing) return LV_RES_OK;
|
|
||||||
/*Stop if the object is deleted*/
|
|
||||||
if(e->deleted) return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
event_dsc = lv_obj_get_event_dsc(e->current_target, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res == LV_RES_OK && e->current_target->parent && event_is_bubbled(e)) {
|
|
||||||
e->current_target = e->current_target->parent;
|
|
||||||
res = event_send_core(e);
|
|
||||||
if(res != LV_RES_OK) return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool event_is_bubbled(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(e->stop_bubbling) return false;
|
|
||||||
|
|
||||||
/*Event codes that always bubble*/
|
|
||||||
switch(e->code) {
|
|
||||||
case LV_EVENT_CHILD_CREATED:
|
|
||||||
case LV_EVENT_CHILD_DELETED:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Check other codes only if bubbling is enabled*/
|
|
||||||
if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_BUBBLE) == false) return false;
|
|
||||||
|
|
||||||
switch(e->code) {
|
|
||||||
case LV_EVENT_HIT_TEST:
|
|
||||||
case LV_EVENT_COVER_CHECK:
|
|
||||||
case LV_EVENT_REFR_EXT_DRAW_SIZE:
|
|
||||||
case LV_EVENT_DRAW_MAIN_BEGIN:
|
|
||||||
case LV_EVENT_DRAW_MAIN:
|
|
||||||
case LV_EVENT_DRAW_MAIN_END:
|
|
||||||
case LV_EVENT_DRAW_POST_BEGIN:
|
|
||||||
case LV_EVENT_DRAW_POST:
|
|
||||||
case LV_EVENT_DRAW_POST_END:
|
|
||||||
case LV_EVENT_DRAW_PART_BEGIN:
|
|
||||||
case LV_EVENT_DRAW_PART_END:
|
|
||||||
case LV_EVENT_REFRESH:
|
|
||||||
case LV_EVENT_DELETE:
|
|
||||||
case LV_EVENT_CHILD_CREATED:
|
|
||||||
case LV_EVENT_CHILD_DELETED:
|
|
||||||
case LV_EVENT_CHILD_CHANGED:
|
|
||||||
case LV_EVENT_SIZE_CHANGED:
|
|
||||||
case LV_EVENT_STYLE_CHANGED:
|
|
||||||
case LV_EVENT_GET_SELF_SIZE:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,363 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_event.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_EVENT_H
|
|
||||||
#define LV_EVENT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
struct _lv_event_dsc_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of event being sent to the object.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
LV_EVENT_ALL = 0,
|
|
||||||
|
|
||||||
/** Input device events*/
|
|
||||||
LV_EVENT_PRESSED, /**< The object has been pressed*/
|
|
||||||
LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/
|
|
||||||
LV_EVENT_PRESS_LOST, /**< The object is still being pressed but slid cursor/finger off of the object */
|
|
||||||
LV_EVENT_SHORT_CLICKED, /**< The object was pressed for a short period of time, then released it. Not called if scrolled.*/
|
|
||||||
LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not called if scrolled.*/
|
|
||||||
LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.*/
|
|
||||||
LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/
|
|
||||||
LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/
|
|
||||||
LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified*/
|
|
||||||
LV_EVENT_SCROLL_END, /**< Scrolling ends*/
|
|
||||||
LV_EVENT_SCROLL, /**< Scrolling*/
|
|
||||||
LV_EVENT_GESTURE, /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_get_act());` */
|
|
||||||
LV_EVENT_KEY, /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_get_act());`*/
|
|
||||||
LV_EVENT_FOCUSED, /**< The object is focused*/
|
|
||||||
LV_EVENT_DEFOCUSED, /**< The object is defocused*/
|
|
||||||
LV_EVENT_LEAVE, /**< The object is defocused but still selected*/
|
|
||||||
LV_EVENT_HIT_TEST, /**< Perform advanced hit-testing*/
|
|
||||||
|
|
||||||
/** Drawing events*/
|
|
||||||
LV_EVENT_COVER_CHECK, /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/
|
|
||||||
LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `lv_coord_t *` to store the size.*/
|
|
||||||
LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase*/
|
|
||||||
LV_EVENT_DRAW_MAIN, /**< Perform the main drawing*/
|
|
||||||
LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase*/
|
|
||||||
LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/
|
|
||||||
LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/
|
|
||||||
LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/
|
|
||||||
LV_EVENT_DRAW_PART_BEGIN, /**< Starting to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. */
|
|
||||||
LV_EVENT_DRAW_PART_END, /**< Finishing to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. */
|
|
||||||
|
|
||||||
/** Special events*/
|
|
||||||
LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved)*/
|
|
||||||
LV_EVENT_INSERT, /**< A text is inserted to the object. The event data is `char *` being inserted.*/
|
|
||||||
LV_EVENT_REFRESH, /**< Notify the object to refresh something on it (for the user)*/
|
|
||||||
LV_EVENT_READY, /**< A process has finished*/
|
|
||||||
LV_EVENT_CANCEL, /**< A process has been cancelled */
|
|
||||||
|
|
||||||
/** Other events*/
|
|
||||||
LV_EVENT_DELETE, /**< Object is being deleted*/
|
|
||||||
LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */
|
|
||||||
LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/
|
|
||||||
LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents*/
|
|
||||||
LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/
|
|
||||||
LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired*/
|
|
||||||
LV_EVENT_SCREEN_LOADED, /**< A screen was loaded*/
|
|
||||||
LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded*/
|
|
||||||
LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed*/
|
|
||||||
LV_EVENT_STYLE_CHANGED, /**< Object's style has changed*/
|
|
||||||
LV_EVENT_LAYOUT_CHANGED, /**< The children position has changed due to a layout recalculation*/
|
|
||||||
LV_EVENT_GET_SELF_SIZE, /**< Get the internal size of a widget*/
|
|
||||||
|
|
||||||
_LV_EVENT_LAST, /** Number of default events*/
|
|
||||||
|
|
||||||
|
|
||||||
LV_EVENT_PREPROCESS = 0x80, /** This is a flag that can be set with an event so it's processed
|
|
||||||
before the class default event processing */
|
|
||||||
} lv_event_code_t;
|
|
||||||
|
|
||||||
typedef struct _lv_event_t {
|
|
||||||
struct _lv_obj_t * target;
|
|
||||||
struct _lv_obj_t * current_target;
|
|
||||||
lv_event_code_t code;
|
|
||||||
void * user_data;
|
|
||||||
void * param;
|
|
||||||
struct _lv_event_t * prev;
|
|
||||||
uint8_t deleted : 1;
|
|
||||||
uint8_t stop_processing : 1;
|
|
||||||
uint8_t stop_bubbling : 1;
|
|
||||||
} lv_event_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Event callback.
|
|
||||||
* Events are used to notify the user of some action being taken on the object.
|
|
||||||
* For details, see ::lv_event_t.
|
|
||||||
*/
|
|
||||||
typedef void (*lv_event_cb_t)(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used as the event parameter of ::LV_EVENT_HIT_TEST to check if an `point` can click the object or not.
|
|
||||||
* `res` should be set like this:
|
|
||||||
* - If already set to `false` an other event wants that point non clickable. If you want to respect it leave it as `false` or set `true` to overwrite it.
|
|
||||||
* - If already set `true` and `point` shouldn't be clickable set to `false`
|
|
||||||
* - If already set to `true` you agree that `point` can click the object leave it as `true`
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
const lv_point_t * point; /**< A point relative to screen to check if it can click the object or not*/
|
|
||||||
bool res; /**< true: `point` can click the object; false: it cannot*/
|
|
||||||
} lv_hit_test_info_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not.
|
|
||||||
* In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check
|
|
||||||
* and `lv_event_set_cover_res(e, res)` to set the result.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
lv_cover_res_t res;
|
|
||||||
const lv_area_t * area;
|
|
||||||
} lv_cover_check_info_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an event to the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param event_code the type of the event from `lv_event_t`
|
|
||||||
* @param param arbitrary data depending on the widget type and the event. (Usually `NULL`)
|
|
||||||
* @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event_code
|
|
||||||
*/
|
|
||||||
lv_res_t lv_event_send(struct _lv_obj_t * obj, lv_event_code_t event_code, void * param);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by the widgets internally to call the ancestor widget types's event handler
|
|
||||||
* @param class_p pointer to the class of the widget (NOT the ancestor class)
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return LV_RES_OK: the target object was not deleted in the event; LV_RES_INV: it was deleted in the event_code
|
|
||||||
*/
|
|
||||||
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the object originally targeted by the event. It's the same even if the event is bubbled.
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return the target of the event_code
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_event_get_target(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current target of the event. It's the object which event handler being called.
|
|
||||||
* If the event is not bubbled it's the same as "normal" target.
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return pointer to the current target of the event_code
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_event_get_current_target(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the event code of an event
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return the event code. (E.g. `LV_EVENT_CLICKED`, `LV_EVENT_FOCUSED`, etc)
|
|
||||||
*/
|
|
||||||
lv_event_code_t lv_event_get_code(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the parameter passed when the event was sent
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return pointer to the parameter
|
|
||||||
*/
|
|
||||||
void * lv_event_get_param(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user_data passed when the event was registered on the object
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
* @return pointer to the user_data
|
|
||||||
*/
|
|
||||||
void * lv_event_get_user_data(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop the event from bubbling.
|
|
||||||
* This is only valid when called in the middle of an event processing chain.
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
*/
|
|
||||||
void lv_event_stop_bubbling(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop processing this event.
|
|
||||||
* This is only valid when called in the middle of an event processing chain.
|
|
||||||
* @param e pointer to the event descriptor
|
|
||||||
*/
|
|
||||||
void lv_event_stop_processing(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a new, custom event ID.
|
|
||||||
* It can be used the same way as e.g. `LV_EVENT_CLICKED` to send custom events
|
|
||||||
* @return the new event id
|
|
||||||
* @example
|
|
||||||
* uint32_t LV_EVENT_MINE = 0;
|
|
||||||
* ...
|
|
||||||
* e = lv_event_register_id();
|
|
||||||
* ...
|
|
||||||
* lv_event_send(obj, LV_EVENT_MINE, &some_data);
|
|
||||||
*/
|
|
||||||
uint32_t lv_event_register_id(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Nested events can be called and one of them might belong to an object that is being deleted.
|
|
||||||
* Mark this object's `event_temp_data` deleted to know that its `lv_event_send` should return `LV_RES_INV`
|
|
||||||
* @param obj pointer to an object to mark as deleted
|
|
||||||
*/
|
|
||||||
void _lv_event_mark_deleted(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an event handler function for an object.
|
|
||||||
* Used by the user to react on event which happens with the object.
|
|
||||||
* An object can have multiple event handler. They will be called in the same order as they were added.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param filter and event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be sued the receive all the events.
|
|
||||||
* @param event_cb the new event function
|
|
||||||
* @param user_data custom data data will be available in `event_cb`
|
|
||||||
* @return a pointer the event descriptor. Can be used in ::lv_obj_remove_event_dsc
|
|
||||||
*/
|
|
||||||
struct _lv_event_dsc_t * lv_obj_add_event_cb(struct _lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,
|
|
||||||
void * user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an event handler function for an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param event_cb the event function to remove, or `NULL` to remove the firstly added event callback
|
|
||||||
* @return true if any event handlers were removed
|
|
||||||
*/
|
|
||||||
bool lv_obj_remove_event_cb(struct _lv_obj_t * obj, lv_event_cb_t event_cb);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an event handler function with a specific user_data from an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param event_cb the event function to remove, or `NULL` only `user_data` matters.
|
|
||||||
* @param event_user_data the user_data specified in ::lv_obj_add_event_cb
|
|
||||||
* @return true if any event handlers were removed
|
|
||||||
*/
|
|
||||||
bool lv_obj_remove_event_cb_with_user_data(struct _lv_obj_t * obj, lv_event_cb_t event_cb,
|
|
||||||
const void * event_user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED because doesn't work if multiple event handlers are added to an object.
|
|
||||||
* Remove an event handler function for an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param event_dsc pointer to an event descriptor to remove (returned by ::lv_obj_add_event_cb)
|
|
||||||
* @return true if any event handlers were removed
|
|
||||||
*/
|
|
||||||
bool lv_obj_remove_event_dsc(struct _lv_obj_t * obj, struct _lv_event_dsc_t * event_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The user data of an event object event callback. Always the first match with `event_cb` will be returned.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param event_cb the event function
|
|
||||||
* @return the user_data
|
|
||||||
*/
|
|
||||||
void * lv_obj_get_event_user_data(struct _lv_obj_t * obj, lv_event_cb_t event_cb);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the input device passed as parameter to indev related events.
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return the indev that triggered the event or NULL if called on a not indev related event
|
|
||||||
*/
|
|
||||||
lv_indev_t * lv_event_get_indev(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the part draw descriptor passed as parameter to `LV_EVENT_DRAW_PART_BEGIN/END`.
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return the part draw descriptor to hook the drawing or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
lv_obj_draw_part_dsc_t * lv_event_get_draw_part_dsc(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the draw context which should be the first parameter of the draw functions.
|
|
||||||
* Namely: `LV_EVENT_DRAW_MAIN/POST`, `LV_EVENT_DRAW_MAIN/POST_BEGIN`, `LV_EVENT_DRAW_MAIN/POST_END`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return pointer to a draw context or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
lv_draw_ctx_t * lv_event_get_draw_ctx(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the old area of the object before its size was changed. Can be used in `LV_EVENT_SIZE_CHANGED`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return the old absolute area of the object or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
const lv_area_t * lv_event_get_old_size(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the key passed as parameter to an event. Can be used in `LV_EVENT_KEY`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return the triggering key or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
uint32_t lv_event_get_key(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the animation descriptor of a scrolling. Can be used in `LV_EVENT_SCROLL_BEGIN`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return the animation that will scroll the object. (can be modified as required)
|
|
||||||
*/
|
|
||||||
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the new extra draw size. Can be used in `LV_EVENT_REFR_EXT_DRAW_SIZE`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @param size The new extra draw size
|
|
||||||
*/
|
|
||||||
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to an `lv_point_t` variable in which the self size should be saved (width in `point->x` and height `point->y`).
|
|
||||||
* Can be used in `LV_EVENT_GET_SELF_SIZE`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return pointer to `lv_point_t` or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
lv_point_t * lv_event_get_self_size_info(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to an `lv_hit_test_info_t` variable in which the hit test result should be saved. Can be used in `LV_EVENT_HIT_TEST`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return pointer to `lv_hit_test_info_t` or NULL if called on an unrelated event
|
|
||||||
*/
|
|
||||||
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to an area which should be examined whether the object fully covers it or not.
|
|
||||||
* Can be used in `LV_EVENT_HIT_TEST`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @return an area with absolute coordinates to check
|
|
||||||
*/
|
|
||||||
const lv_area_t * lv_event_get_cover_area(lv_event_t * e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the result of cover checking. Can be used in `LV_EVENT_COVER_CHECK`
|
|
||||||
* @param e pointer to an event
|
|
||||||
* @param res an element of ::lv_cover_check_info_t
|
|
||||||
*/
|
|
||||||
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_EVENT_H*/
|
|
@ -1,494 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_group.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "lv_group.h"
|
|
||||||
#include "../misc/lv_gc.h"
|
|
||||||
#include "../core/lv_obj.h"
|
|
||||||
#include "../core/lv_indev.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static bool focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
|
||||||
void * (*move)(const lv_ll_t *, const void *));
|
|
||||||
static void lv_group_refocus(lv_group_t * g);
|
|
||||||
static lv_indev_t * get_indev(const lv_group_t * g);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static lv_group_t * default_group;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void _lv_group_init(void)
|
|
||||||
{
|
|
||||||
_lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_group_t * lv_group_create(void)
|
|
||||||
{
|
|
||||||
lv_group_t * group = _lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
|
||||||
LV_ASSERT_MALLOC(group);
|
|
||||||
if(group == NULL) return NULL;
|
|
||||||
_lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
|
||||||
|
|
||||||
group->obj_focus = NULL;
|
|
||||||
group->frozen = 0;
|
|
||||||
group->focus_cb = NULL;
|
|
||||||
group->edge_cb = NULL;
|
|
||||||
group->editing = 0;
|
|
||||||
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
|
|
||||||
group->wrap = 1;
|
|
||||||
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
group->user_data = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_del(lv_group_t * group)
|
|
||||||
{
|
|
||||||
/*Defocus the currently focused object*/
|
|
||||||
if(group->obj_focus != NULL) {
|
|
||||||
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Remove the objects from the group*/
|
|
||||||
lv_obj_t ** obj;
|
|
||||||
_LV_LL_READ(&group->obj_ll, obj) {
|
|
||||||
if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Remove the group from any indev devices */
|
|
||||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
|
||||||
while(indev) {
|
|
||||||
if(indev->group == group) {
|
|
||||||
lv_indev_set_group(indev, NULL);
|
|
||||||
}
|
|
||||||
indev = lv_indev_get_next(indev);
|
|
||||||
}
|
|
||||||
|
|
||||||
_lv_ll_clear(&(group->obj_ll));
|
|
||||||
_lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
|
|
||||||
lv_mem_free(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_default(lv_group_t * group)
|
|
||||||
{
|
|
||||||
default_group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_group_t * lv_group_get_default(void)
|
|
||||||
{
|
|
||||||
return default_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(group == NULL) return;
|
|
||||||
|
|
||||||
LV_LOG_TRACE("begin");
|
|
||||||
|
|
||||||
/*Do not add the object twice*/
|
|
||||||
lv_obj_t ** obj_i;
|
|
||||||
_LV_LL_READ(&group->obj_ll, obj_i) {
|
|
||||||
if((*obj_i) == obj) {
|
|
||||||
LV_LOG_INFO("the object is already added to this group");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If the object is already in a group and focused then refocus it*/
|
|
||||||
lv_group_t * group_cur = lv_obj_get_group(obj);
|
|
||||||
if(group_cur) {
|
|
||||||
if(obj->spec_attr->group_p && *(obj->spec_attr->group_p->obj_focus) == obj) {
|
|
||||||
lv_group_refocus(group_cur);
|
|
||||||
|
|
||||||
LV_LOG_INFO("changing object's group");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
|
|
||||||
obj->spec_attr->group_p = group;
|
|
||||||
|
|
||||||
lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll);
|
|
||||||
LV_ASSERT_MALLOC(next);
|
|
||||||
if(next == NULL) return;
|
|
||||||
*next = obj;
|
|
||||||
|
|
||||||
/*If the head and the tail is equal then there is only one object in the linked list.
|
|
||||||
*In this case automatically activate it*/
|
|
||||||
if(_lv_ll_get_head(&group->obj_ll) == next) {
|
|
||||||
lv_group_refocus(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_LOG_TRACE("finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2)
|
|
||||||
{
|
|
||||||
lv_group_t * g1 = lv_obj_get_group(obj1);
|
|
||||||
lv_group_t * g2 = lv_obj_get_group(obj2);
|
|
||||||
if(g1 != g2) return;
|
|
||||||
if(g1 == NULL) return;
|
|
||||||
|
|
||||||
/*Do not add the object twice*/
|
|
||||||
lv_obj_t ** obj_i;
|
|
||||||
_LV_LL_READ(&g1->obj_ll, obj_i) {
|
|
||||||
if((*obj_i) == obj1)(*obj_i) = obj2;
|
|
||||||
else if((*obj_i) == obj2)(*obj_i) = obj1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*g1->obj_focus == obj1) lv_group_focus_obj(obj2);
|
|
||||||
else if(*g1->obj_focus == obj2) lv_group_focus_obj(obj1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_remove_obj(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_group_t * g = lv_obj_get_group(obj);
|
|
||||||
if(g == NULL) return;
|
|
||||||
|
|
||||||
LV_LOG_TRACE("begin");
|
|
||||||
|
|
||||||
/*Focus on the next object*/
|
|
||||||
if(g->obj_focus && *g->obj_focus == obj) {
|
|
||||||
if(g->frozen) g->frozen = 0;
|
|
||||||
|
|
||||||
/*If this is the only object in the group then focus to nothing.*/
|
|
||||||
if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
|
||||||
lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
|
||||||
}
|
|
||||||
/*If there more objects in the group then focus to the next/prev object*/
|
|
||||||
else {
|
|
||||||
lv_group_refocus(g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If the focuses object is still the same then it was the only object in the group but it will
|
|
||||||
*be deleted. Set the `obj_focus` to NULL to get back to the initial state of the group with
|
|
||||||
*zero objects*/
|
|
||||||
if(g->obj_focus && *g->obj_focus == obj) {
|
|
||||||
g->obj_focus = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Search the object and remove it from its group*/
|
|
||||||
lv_obj_t ** i;
|
|
||||||
_LV_LL_READ(&g->obj_ll, i) {
|
|
||||||
if(*i == obj) {
|
|
||||||
_lv_ll_remove(&g->obj_ll, i);
|
|
||||||
lv_mem_free(i);
|
|
||||||
if(obj->spec_attr) obj->spec_attr->group_p = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LV_LOG_TRACE("finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_remove_all_objs(lv_group_t * group)
|
|
||||||
{
|
|
||||||
/*Defocus the currently focused object*/
|
|
||||||
if(group->obj_focus != NULL) {
|
|
||||||
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
|
||||||
group->obj_focus = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Remove the objects from the group*/
|
|
||||||
lv_obj_t ** obj;
|
|
||||||
_LV_LL_READ(&group->obj_ll, obj) {
|
|
||||||
if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lv_ll_clear(&(group->obj_ll));
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_focus_obj(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj == NULL) return;
|
|
||||||
lv_group_t * g = lv_obj_get_group(obj);
|
|
||||||
if(g == NULL) return;
|
|
||||||
|
|
||||||
if(g->frozen != 0) return;
|
|
||||||
|
|
||||||
/*On defocus edit mode must be leaved*/
|
|
||||||
lv_group_set_editing(g, false);
|
|
||||||
|
|
||||||
lv_obj_t ** i;
|
|
||||||
_LV_LL_READ(&g->obj_ll, i) {
|
|
||||||
if(*i == obj) {
|
|
||||||
if(g->obj_focus != NULL && obj != *g->obj_focus) { /*Do not defocus if the same object needs to be focused again*/
|
|
||||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
lv_obj_invalidate(*g->obj_focus);
|
|
||||||
}
|
|
||||||
|
|
||||||
g->obj_focus = i;
|
|
||||||
|
|
||||||
if(g->obj_focus != NULL) {
|
|
||||||
if(g->focus_cb) g->focus_cb(g);
|
|
||||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, get_indev(g));
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
lv_obj_invalidate(*g->obj_focus);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_focus_next(lv_group_t * group)
|
|
||||||
{
|
|
||||||
bool focus_changed = focus_next_core(group, _lv_ll_get_head, _lv_ll_get_next);
|
|
||||||
if(group->edge_cb) {
|
|
||||||
if(!focus_changed)
|
|
||||||
group->edge_cb(group, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_focus_prev(lv_group_t * group)
|
|
||||||
{
|
|
||||||
bool focus_changed = focus_next_core(group, _lv_ll_get_tail, _lv_ll_get_prev);
|
|
||||||
if(group->edge_cb) {
|
|
||||||
if(!focus_changed)
|
|
||||||
group->edge_cb(group, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
|
||||||
{
|
|
||||||
if(en == false) group->frozen = 0;
|
|
||||||
else group->frozen = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
|
||||||
{
|
|
||||||
lv_obj_t * act = lv_group_get_focused(group);
|
|
||||||
if(act == NULL) return LV_RES_OK;
|
|
||||||
|
|
||||||
if(lv_obj_has_state(act, LV_STATE_DISABLED)) return LV_RES_OK;
|
|
||||||
|
|
||||||
return lv_event_send(act, LV_EVENT_KEY, &c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
|
||||||
{
|
|
||||||
group->focus_cb = focus_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb)
|
|
||||||
{
|
|
||||||
group->edge_cb = edge_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_editing(lv_group_t * group, bool edit)
|
|
||||||
{
|
|
||||||
if(group == NULL) return;
|
|
||||||
uint8_t en_val = edit ? 1 : 0;
|
|
||||||
|
|
||||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
|
||||||
|
|
||||||
group->editing = en_val;
|
|
||||||
lv_obj_t * focused = lv_group_get_focused(group);
|
|
||||||
|
|
||||||
if(focused) {
|
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
|
|
||||||
lv_obj_invalidate(focused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
|
||||||
{
|
|
||||||
group->refocus_policy = policy & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_group_set_wrap(lv_group_t * group, bool en)
|
|
||||||
{
|
|
||||||
group->wrap = en ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group)
|
|
||||||
{
|
|
||||||
if(!group) return NULL;
|
|
||||||
if(group->obj_focus == NULL) return NULL;
|
|
||||||
|
|
||||||
return *group->obj_focus;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group)
|
|
||||||
{
|
|
||||||
if(!group) return NULL;
|
|
||||||
return group->focus_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group)
|
|
||||||
{
|
|
||||||
if(!group) return NULL;
|
|
||||||
return group->edge_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_group_get_editing(const lv_group_t * group)
|
|
||||||
{
|
|
||||||
if(!group) return false;
|
|
||||||
return group->editing ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_group_get_wrap(lv_group_t * group)
|
|
||||||
{
|
|
||||||
if(!group) return false;
|
|
||||||
return group->wrap ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lv_group_get_obj_count(lv_group_t * group)
|
|
||||||
{
|
|
||||||
return _lv_ll_get_len(&group->obj_ll);
|
|
||||||
}
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void lv_group_refocus(lv_group_t * g)
|
|
||||||
{
|
|
||||||
/*Refocus must temporarily allow wrapping to work correctly*/
|
|
||||||
uint8_t temp_wrap = g->wrap;
|
|
||||||
g->wrap = 1;
|
|
||||||
|
|
||||||
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
|
|
||||||
lv_group_focus_next(g);
|
|
||||||
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
|
|
||||||
lv_group_focus_prev(g);
|
|
||||||
/*Restore wrap property*/
|
|
||||||
g->wrap = temp_wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
|
||||||
void * (*move)(const lv_ll_t *, const void *))
|
|
||||||
{
|
|
||||||
bool focus_changed = false;
|
|
||||||
if(group->frozen) return focus_changed;
|
|
||||||
|
|
||||||
lv_obj_t ** obj_next = group->obj_focus;
|
|
||||||
lv_obj_t ** obj_sentinel = NULL;
|
|
||||||
bool can_move = true;
|
|
||||||
bool can_begin = true;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
if(obj_next == NULL) {
|
|
||||||
if(group->wrap || obj_sentinel == NULL) {
|
|
||||||
if(!can_begin) return focus_changed;
|
|
||||||
obj_next = begin(&group->obj_ll);
|
|
||||||
can_move = false;
|
|
||||||
can_begin = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Currently focused object is the last/first in the group, keep it that way*/
|
|
||||||
return focus_changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj_sentinel == NULL) {
|
|
||||||
obj_sentinel = obj_next;
|
|
||||||
if(obj_sentinel == NULL) return focus_changed; /*Group is empty*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if(can_move) {
|
|
||||||
obj_next = move(&group->obj_ll, obj_next);
|
|
||||||
|
|
||||||
/*Give up if we walked the entire list and haven't found another visible object*/
|
|
||||||
if(obj_next == obj_sentinel) return focus_changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
can_move = true;
|
|
||||||
|
|
||||||
if(obj_next == NULL) continue;
|
|
||||||
if(lv_obj_get_state(*obj_next) & LV_STATE_DISABLED) continue;
|
|
||||||
|
|
||||||
/*Hidden objects don't receive focus.
|
|
||||||
*If any parent is hidden, the object is also hidden)*/
|
|
||||||
lv_obj_t * parent = *obj_next;
|
|
||||||
while(parent) {
|
|
||||||
if(lv_obj_has_flag(parent, LV_OBJ_FLAG_HIDDEN)) break;
|
|
||||||
parent = lv_obj_get_parent(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent && lv_obj_has_flag(parent, LV_OBJ_FLAG_HIDDEN)) continue;
|
|
||||||
|
|
||||||
/*If we got her a good candidate is found*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj_next == group->obj_focus) return focus_changed; /*There's only one visible object and it's already focused*/
|
|
||||||
|
|
||||||
if(group->obj_focus) {
|
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
|
||||||
if(res != LV_RES_OK) return focus_changed;
|
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
|
||||||
}
|
|
||||||
|
|
||||||
group->obj_focus = obj_next;
|
|
||||||
|
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
|
||||||
if(res != LV_RES_OK) return focus_changed;
|
|
||||||
|
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
|
||||||
|
|
||||||
if(group->focus_cb) group->focus_cb(group);
|
|
||||||
focus_changed = true;
|
|
||||||
return focus_changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find an indev preferably with KEYPAD or ENCOEDR type that uses the given group.
|
|
||||||
* In other words, find an indev, that is related to the given group.
|
|
||||||
* In the worst case simply return the latest indev
|
|
||||||
* @param g a group the find in the indevs
|
|
||||||
* @return the suggested indev
|
|
||||||
*/
|
|
||||||
static lv_indev_t * get_indev(const lv_group_t * g)
|
|
||||||
{
|
|
||||||
lv_indev_t * indev_encoder = NULL;
|
|
||||||
lv_indev_t * indev_group = NULL;
|
|
||||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
|
||||||
while(indev) {
|
|
||||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
|
||||||
if(indev->group == g) {
|
|
||||||
/*Prefer KEYPAD*/
|
|
||||||
if(indev_type == LV_INDEV_TYPE_KEYPAD) return indev;
|
|
||||||
if(indev_type == LV_INDEV_TYPE_ENCODER) indev_encoder = indev;
|
|
||||||
indev_group = indev;
|
|
||||||
}
|
|
||||||
indev = lv_indev_get_next(indev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(indev_encoder) return indev_encoder;
|
|
||||||
if(indev_group) return indev_group;
|
|
||||||
|
|
||||||
/*In lack of a better option use the first input device. (It can be NULL if there is no input device)*/
|
|
||||||
return lv_indev_get_next(NULL);
|
|
||||||
}
|
|
||||||
|
|
@ -1,266 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_group.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_GROUP_H
|
|
||||||
#define LV_GROUP_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#include "../lv_conf_internal.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "../misc/lv_ll.h"
|
|
||||||
#include "../misc/lv_types.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LV_KEY_UP = 17, /*0x11*/
|
|
||||||
LV_KEY_DOWN = 18, /*0x12*/
|
|
||||||
LV_KEY_RIGHT = 19, /*0x13*/
|
|
||||||
LV_KEY_LEFT = 20, /*0x14*/
|
|
||||||
LV_KEY_ESC = 27, /*0x1B*/
|
|
||||||
LV_KEY_DEL = 127, /*0x7F*/
|
|
||||||
LV_KEY_BACKSPACE = 8, /*0x08*/
|
|
||||||
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
|
|
||||||
LV_KEY_NEXT = 9, /*0x09, '\t'*/
|
|
||||||
LV_KEY_PREV = 11, /*0x0B, '*/
|
|
||||||
LV_KEY_HOME = 2, /*0x02, STX*/
|
|
||||||
LV_KEY_END = 3, /*0x03, ETX*/
|
|
||||||
};
|
|
||||||
typedef uint8_t lv_key_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
struct _lv_group_t;
|
|
||||||
|
|
||||||
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
|
|
||||||
typedef void (*lv_group_edge_cb_t)(struct _lv_group_t *, bool);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Groups can be used to logically hold objects so that they can be individually focused.
|
|
||||||
* They are NOT for laying out objects on a screen (try layouts for that).
|
|
||||||
*/
|
|
||||||
typedef struct _lv_group_t {
|
|
||||||
lv_ll_t obj_ll; /**< Linked list to store the objects in the group*/
|
|
||||||
struct _lv_obj_t ** obj_focus; /**< The object in focus*/
|
|
||||||
|
|
||||||
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
|
|
||||||
lv_group_edge_cb_t edge_cb; /**< A function to call when an edge is reached, no more focus
|
|
||||||
targets are available in this direction (to allow edge feedback
|
|
||||||
like a sound or a scroll bounce) */
|
|
||||||
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
void * user_data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t frozen : 1; /**< 1: can't focus to new object*/
|
|
||||||
uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/
|
|
||||||
uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on
|
|
||||||
deletion.*/
|
|
||||||
uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end
|
|
||||||
of list.*/
|
|
||||||
} lv_group_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_GROUP_REFOCUS_POLICY_NEXT = 0,
|
|
||||||
LV_GROUP_REFOCUS_POLICY_PREV = 1
|
|
||||||
} lv_group_refocus_policy_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init. the group module
|
|
||||||
* @remarks Internal function, do not call directly.
|
|
||||||
*/
|
|
||||||
void _lv_group_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new object group
|
|
||||||
* @return pointer to the new object group
|
|
||||||
*/
|
|
||||||
lv_group_t * lv_group_create(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a group object
|
|
||||||
* @param group pointer to a group
|
|
||||||
*/
|
|
||||||
void lv_group_del(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true`
|
|
||||||
* @param group pointer to a group (can be `NULL`)
|
|
||||||
*/
|
|
||||||
void lv_group_set_default(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the default group
|
|
||||||
* @return pointer to the default group
|
|
||||||
*/
|
|
||||||
lv_group_t * lv_group_get_default(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an object to a group
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param obj pointer to an object to add
|
|
||||||
*/
|
|
||||||
void lv_group_add_obj(lv_group_t * group, struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swap 2 object in a group. The object must be in the same group
|
|
||||||
* @param obj1 pointer to an object
|
|
||||||
* @param obj2 pointer to an other object
|
|
||||||
*/
|
|
||||||
void lv_group_swap_obj(struct _lv_obj_t * obj1, struct _lv_obj_t * obj2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an object from its group
|
|
||||||
* @param obj pointer to an object to remove
|
|
||||||
*/
|
|
||||||
void lv_group_remove_obj(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all objects from a group
|
|
||||||
* @param group pointer to a group
|
|
||||||
*/
|
|
||||||
void lv_group_remove_all_objs(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Focus on an object (defocus the current)
|
|
||||||
* @param obj pointer to an object to focus on
|
|
||||||
*/
|
|
||||||
void lv_group_focus_obj(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Focus the next object in a group (defocus the current)
|
|
||||||
* @param group pointer to a group
|
|
||||||
*/
|
|
||||||
void lv_group_focus_next(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Focus the previous object in a group (defocus the current)
|
|
||||||
* @param group pointer to a group
|
|
||||||
*/
|
|
||||||
void lv_group_focus_prev(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not let to change the focus from the current object
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param en true: freeze, false: release freezing (normal mode)
|
|
||||||
*/
|
|
||||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a control character to the focuses object of a group
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param c a character (use LV_KEY_.. to navigate)
|
|
||||||
* @return result of focused object in group.
|
|
||||||
*/
|
|
||||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a function for a group which will be called when a new object is focused
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param focus_cb the call back function or NULL if unused
|
|
||||||
*/
|
|
||||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a function for a group which will be called when a focus edge is reached
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param edge_cb the call back function or NULL if unused
|
|
||||||
*/
|
|
||||||
void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether the next or previous item in a group is focused if the currently focused obj is
|
|
||||||
* deleted.
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @param policy new refocus policy enum
|
|
||||||
*/
|
|
||||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manually set the current mode (edit or navigate).
|
|
||||||
* @param group pointer to group
|
|
||||||
* @param edit true: edit mode; false: navigate mode
|
|
||||||
*/
|
|
||||||
void lv_group_set_editing(lv_group_t * group, bool edit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether focus next/prev will allow wrapping from first->last or last->first object.
|
|
||||||
* @param group pointer to group
|
|
||||||
* @param en true: wrapping enabled; false: wrapping disabled
|
|
||||||
*/
|
|
||||||
void lv_group_set_wrap(lv_group_t * group, bool en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the focused object or NULL if there isn't one
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @return pointer to the focused object
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_group_get_focused(const lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the focus callback function of a group
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @return the call back function or NULL if not set
|
|
||||||
*/
|
|
||||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the edge callback function of a group
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @return the call back function or NULL if not set
|
|
||||||
*/
|
|
||||||
lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current mode (edit or navigate).
|
|
||||||
* @param group pointer to group
|
|
||||||
* @return true: edit mode; false: navigate mode
|
|
||||||
*/
|
|
||||||
bool lv_group_get_editing(const lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
|
||||||
* @param group pointer to group
|
|
||||||
* @param en true: wrapping enabled; false: wrapping disabled
|
|
||||||
*/
|
|
||||||
bool lv_group_get_wrap(lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of object in the group
|
|
||||||
* @param group pointer to a group
|
|
||||||
* @return number of objects in the group
|
|
||||||
*/
|
|
||||||
uint32_t lv_group_get_obj_count(lv_group_t * group);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_GROUP_H*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,176 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_indev.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_INDEV_H
|
|
||||||
#define LV_INDEV_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "../hal/lv_hal_indev.h"
|
|
||||||
#include "lv_group.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called periodically to read the input devices
|
|
||||||
* @param timer pointer to a timer to read
|
|
||||||
*/
|
|
||||||
void lv_indev_read_timer_cb(lv_timer_t * timer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable one or all input devices (default enabled)
|
|
||||||
* @param indev pointer to an input device or NULL to enable/disable all of them
|
|
||||||
* @param en true to enable, false to disable
|
|
||||||
*/
|
|
||||||
void lv_indev_enable(lv_indev_t * indev, bool en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the currently processed input device. Can be used in action functions too.
|
|
||||||
* @return pointer to the currently processed input device or NULL if no input device processing
|
|
||||||
* right now
|
|
||||||
*/
|
|
||||||
lv_indev_t * lv_indev_get_act(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the type of an input device
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`)
|
|
||||||
*/
|
|
||||||
lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset one or all input devices
|
|
||||||
* @param indev pointer to an input device to reset or NULL to reset all of them
|
|
||||||
* @param obj pointer to an object which triggers the reset.
|
|
||||||
*/
|
|
||||||
void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the long press state of an input device
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
*/
|
|
||||||
void lv_indev_reset_long_press(lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param cur_obj pointer to an object to be used as cursor
|
|
||||||
*/
|
|
||||||
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param group point to a group
|
|
||||||
*/
|
|
||||||
void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the an array of points for LV_INDEV_TYPE_BUTTON.
|
|
||||||
* These points will be assigned to the buttons to press a specific point on the screen
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param group point to a group
|
|
||||||
*/
|
|
||||||
void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param point pointer to a point to store the result
|
|
||||||
*/
|
|
||||||
void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current gesture direct
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return current gesture direct
|
|
||||||
*/
|
|
||||||
lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return the last pressed key (0 on error)
|
|
||||||
*/
|
|
||||||
uint32_t lv_indev_get_key(const lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and
|
|
||||||
* LV_INDEV_TYPE_BUTTON)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return LV_DIR_NONE: no scrolling now
|
|
||||||
* LV_DIR_HOR/VER
|
|
||||||
*/
|
|
||||||
lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and
|
|
||||||
* LV_INDEV_TYPE_BUTTON)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return pointer to the currently scrolled object or NULL if no scrolling by this indev
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and
|
|
||||||
* LV_INDEV_TYPE_BUTTON)
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param point pointer to a point to store the types.pointer.vector
|
|
||||||
*/
|
|
||||||
void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing until the next release
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
*/
|
|
||||||
void lv_indev_wait_release(lv_indev_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a pointer to the currently active object in the currently processed input device.
|
|
||||||
* @return pointer to currently active object or NULL if no active object
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_indev_get_obj_act(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a pointer to the indev read timer to
|
|
||||||
* modify its parameters with `lv_timer_...` functions.
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @return pointer to the indev read refresher timer. (NULL on error)
|
|
||||||
*/
|
|
||||||
lv_timer_t * lv_indev_get_read_timer(lv_disp_t * indev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search the most top, clickable object by a point
|
|
||||||
* @param obj pointer to a start object, typically the screen
|
|
||||||
* @param point pointer to a point for searching the most top child
|
|
||||||
* @return pointer to the found object or NULL if there was no suitable object
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_INDEV_H*/
|
|
@ -1,652 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_indev_scroll.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_indev.h"
|
|
||||||
#include "lv_indev_scroll.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define ELASTIC_SLOWNESS_FACTOR 4 /*Scrolling on elastic parts are slower by this factor*/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc);
|
|
||||||
static void init_scroll_limits(_lv_indev_proc_t * proc);
|
|
||||||
static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs);
|
|
||||||
static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs);
|
|
||||||
static void scroll_limit_diff(_lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y);
|
|
||||||
static lv_coord_t scroll_throw_predict_y(_lv_indev_proc_t * proc);
|
|
||||||
static lv_coord_t scroll_throw_predict_x(_lv_indev_proc_t * proc);
|
|
||||||
static lv_coord_t elastic_diff(lv_obj_t * scroll_obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end,
|
|
||||||
lv_dir_t dir);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void _lv_indev_scroll_handler(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
|
||||||
/*If there is no scroll object yet try to find one*/
|
|
||||||
if(scroll_obj == NULL) {
|
|
||||||
proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x;
|
|
||||||
proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y;
|
|
||||||
|
|
||||||
scroll_obj = find_scroll_obj(proc);
|
|
||||||
if(scroll_obj == NULL) return;
|
|
||||||
|
|
||||||
init_scroll_limits(proc);
|
|
||||||
|
|
||||||
lv_event_send(scroll_obj, LV_EVENT_SCROLL_BEGIN, NULL);
|
|
||||||
if(proc->reset_query) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Set new position or scroll if the vector is not zero*/
|
|
||||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
|
||||||
lv_coord_t diff_x = 0;
|
|
||||||
lv_coord_t diff_y = 0;
|
|
||||||
|
|
||||||
if(proc->types.pointer.scroll_dir == LV_DIR_HOR) {
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
|
||||||
diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
|
||||||
diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj);
|
|
||||||
if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0;
|
|
||||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0;
|
|
||||||
if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0;
|
|
||||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0;
|
|
||||||
|
|
||||||
/*Respect the scroll limit area*/
|
|
||||||
scroll_limit_diff(proc, &diff_x, &diff_y);
|
|
||||||
|
|
||||||
_lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y);
|
|
||||||
if(proc->reset_query) return;
|
|
||||||
proc->types.pointer.scroll_sum.x += diff_x;
|
|
||||||
proc->types.pointer.scroll_sum.y += diff_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void _lv_indev_scroll_throw_handler(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
|
||||||
if(scroll_obj == NULL) return;
|
|
||||||
if(proc->types.pointer.scroll_dir == LV_DIR_NONE) return;
|
|
||||||
|
|
||||||
|
|
||||||
lv_indev_t * indev_act = lv_indev_get_act();
|
|
||||||
lv_coord_t scroll_throw = indev_act->driver->scroll_throw;
|
|
||||||
|
|
||||||
if(lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_MOMENTUM) == false) {
|
|
||||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
|
||||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_scroll_snap_t align_x = lv_obj_get_scroll_snap_x(scroll_obj);
|
|
||||||
lv_scroll_snap_t align_y = lv_obj_get_scroll_snap_y(scroll_obj);
|
|
||||||
|
|
||||||
if(proc->types.pointer.scroll_dir == LV_DIR_VER) {
|
|
||||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
|
||||||
/*If no snapping "throw"*/
|
|
||||||
if(align_y == LV_SCROLL_SNAP_NONE) {
|
|
||||||
proc->types.pointer.scroll_throw_vect.y =
|
|
||||||
proc->types.pointer.scroll_throw_vect.y * (100 - scroll_throw) / 100;
|
|
||||||
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
|
||||||
|
|
||||||
proc->types.pointer.scroll_throw_vect.y = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.y, st, sb,
|
|
||||||
LV_DIR_VER);
|
|
||||||
|
|
||||||
lv_obj_scroll_by(scroll_obj, 0, proc->types.pointer.scroll_throw_vect.y, LV_ANIM_OFF);
|
|
||||||
}
|
|
||||||
/*With snapping find the nearest snap point and scroll there*/
|
|
||||||
else {
|
|
||||||
lv_coord_t diff_y = scroll_throw_predict_y(proc);
|
|
||||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
|
||||||
scroll_limit_diff(proc, NULL, &diff_y);
|
|
||||||
lv_coord_t y = find_snap_point_y(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_y);
|
|
||||||
lv_obj_scroll_by(scroll_obj, 0, diff_y + y, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(proc->types.pointer.scroll_dir == LV_DIR_HOR) {
|
|
||||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
|
||||||
/*If no snapping "throw"*/
|
|
||||||
if(align_x == LV_SCROLL_SNAP_NONE) {
|
|
||||||
proc->types.pointer.scroll_throw_vect.x =
|
|
||||||
proc->types.pointer.scroll_throw_vect.x * (100 - scroll_throw) / 100;
|
|
||||||
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
|
||||||
|
|
||||||
proc->types.pointer.scroll_throw_vect.x = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.x, sl, sr,
|
|
||||||
LV_DIR_HOR);
|
|
||||||
|
|
||||||
lv_obj_scroll_by(scroll_obj, proc->types.pointer.scroll_throw_vect.x, 0, LV_ANIM_OFF);
|
|
||||||
}
|
|
||||||
/*With snapping find the nearest snap point and scroll there*/
|
|
||||||
else {
|
|
||||||
lv_coord_t diff_x = scroll_throw_predict_x(proc);
|
|
||||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
|
||||||
scroll_limit_diff(proc, &diff_x, NULL);
|
|
||||||
lv_coord_t x = find_snap_point_x(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_x);
|
|
||||||
lv_obj_scroll_by(scroll_obj, x + diff_x, 0, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Check if the scroll has finished*/
|
|
||||||
if(proc->types.pointer.scroll_throw_vect.x == 0 && proc->types.pointer.scroll_throw_vect.y == 0) {
|
|
||||||
/*Revert if scrolled in*/
|
|
||||||
/*If vertically scrollable and not controlled by snap*/
|
|
||||||
if(align_y == LV_SCROLL_SNAP_NONE) {
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
|
||||||
if(st > 0 || sb > 0) {
|
|
||||||
if(st < 0) {
|
|
||||||
lv_obj_scroll_by(scroll_obj, 0, st, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
else if(sb < 0) {
|
|
||||||
lv_obj_scroll_by(scroll_obj, 0, -sb, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If horizontally scrollable and not controlled by snap*/
|
|
||||||
if(align_x == LV_SCROLL_SNAP_NONE) {
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
|
||||||
if(sl > 0 || sr > 0) {
|
|
||||||
if(sl < 0) {
|
|
||||||
lv_obj_scroll_by(scroll_obj, sl, 0, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
else if(sr < 0) {
|
|
||||||
lv_obj_scroll_by(scroll_obj, -sr, 0, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_event_send(scroll_obj, LV_EVENT_SCROLL_END, indev_act);
|
|
||||||
if(proc->reset_query) return;
|
|
||||||
|
|
||||||
proc->types.pointer.scroll_dir = LV_DIR_NONE;
|
|
||||||
proc->types.pointer.scroll_obj = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Predict where would a scroll throw end
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param dir `LV_DIR_VER` or `LV_DIR_HOR`
|
|
||||||
* @return the difference compared to the current position when the throw would be finished
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_indev_scroll_throw_predict(lv_indev_t * indev, lv_dir_t dir)
|
|
||||||
{
|
|
||||||
if(indev == NULL) return 0;
|
|
||||||
lv_coord_t v;
|
|
||||||
switch(dir) {
|
|
||||||
case LV_DIR_VER:
|
|
||||||
v = indev->proc.types.pointer.scroll_throw_vect_ori.y;
|
|
||||||
break;
|
|
||||||
case LV_DIR_HOR:
|
|
||||||
v = indev->proc.types.pointer.scroll_throw_vect_ori.x;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t scroll_throw = indev->driver->scroll_throw;
|
|
||||||
lv_coord_t sum = 0;
|
|
||||||
while(v) {
|
|
||||||
sum += v;
|
|
||||||
v = v * (100 - scroll_throw) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_indev_scroll_get_snap_dist(lv_obj_t * obj, lv_point_t * p)
|
|
||||||
{
|
|
||||||
p->x = find_snap_point_x(obj, obj->coords.x1, obj->coords.x2, 0);
|
|
||||||
p->y = find_snap_point_y(obj, obj->coords.y1, obj->coords.y2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_obj_t * obj_candidate = NULL;
|
|
||||||
lv_dir_t dir_candidate = LV_DIR_NONE;
|
|
||||||
lv_indev_t * indev_act = lv_indev_get_act();
|
|
||||||
lv_coord_t scroll_limit = indev_act->driver->scroll_limit;
|
|
||||||
|
|
||||||
/*Go until find a scrollable object in the current direction
|
|
||||||
*More precisely:
|
|
||||||
* 1. Check the pressed object and all of its ancestors and try to find an object which is scrollable
|
|
||||||
* 2. Scrollable means it has some content out of its area
|
|
||||||
* 3. If an object can be scrolled into the current direction then use it ("real match"")
|
|
||||||
* 4. If can be scrolled on the current axis (hor/ver) save it as candidate (at least show an elastic scroll effect)
|
|
||||||
* 5. Use the last candidate. Always the "deepest" parent or the object from point 3*/
|
|
||||||
lv_obj_t * obj_act = proc->types.pointer.act_obj;
|
|
||||||
|
|
||||||
/*Decide if it's a horizontal or vertical scroll*/
|
|
||||||
bool hor_en = false;
|
|
||||||
bool ver_en = false;
|
|
||||||
if(LV_ABS(proc->types.pointer.scroll_sum.x) > LV_ABS(proc->types.pointer.scroll_sum.y)) {
|
|
||||||
hor_en = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ver_en = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(obj_act) {
|
|
||||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) {
|
|
||||||
/*If this object don't want to chain the scroll to the parent stop searching*/
|
|
||||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_HOR) == false && hor_en) break;
|
|
||||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_VER) == false && ver_en) break;
|
|
||||||
|
|
||||||
obj_act = lv_obj_get_parent(obj_act);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Consider both up-down or left/right scrollable according to the current direction*/
|
|
||||||
bool up_en = ver_en;
|
|
||||||
bool down_en = ver_en;
|
|
||||||
bool left_en = hor_en;
|
|
||||||
bool right_en = hor_en;
|
|
||||||
|
|
||||||
/*The object might have disabled some directions.*/
|
|
||||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(obj_act);
|
|
||||||
if((scroll_dir & LV_DIR_LEFT) == 0) left_en = false;
|
|
||||||
if((scroll_dir & LV_DIR_RIGHT) == 0) right_en = false;
|
|
||||||
if((scroll_dir & LV_DIR_TOP) == 0) up_en = false;
|
|
||||||
if((scroll_dir & LV_DIR_BOTTOM) == 0) down_en = false;
|
|
||||||
|
|
||||||
/*The object is scrollable to a direction if its content overflow in that direction.*/
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(obj_act);
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj_act);
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(obj_act);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(obj_act);
|
|
||||||
|
|
||||||
/*If this object is scrollable into the current scroll direction then save it as a candidate.
|
|
||||||
*It's important only to be scrollable on the current axis (hor/ver) because if the scroll
|
|
||||||
*is propagated to this object it can show at least elastic scroll effect.
|
|
||||||
*But if not hor/ver scrollable do not scroll it at all (so it's not a good candidate)*/
|
|
||||||
if((st > 0 || sb > 0) &&
|
|
||||||
((up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
|
||||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit))) {
|
|
||||||
obj_candidate = obj_act;
|
|
||||||
dir_candidate = LV_DIR_VER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((sl > 0 || sr > 0) &&
|
|
||||||
((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
|
||||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit))) {
|
|
||||||
obj_candidate = obj_act;
|
|
||||||
dir_candidate = LV_DIR_HOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(st <= 0) up_en = false;
|
|
||||||
if(sb <= 0) down_en = false;
|
|
||||||
if(sl <= 0) left_en = false;
|
|
||||||
if(sr <= 0) right_en = false;
|
|
||||||
|
|
||||||
/*If the object really can be scrolled into the current direction the use it.*/
|
|
||||||
if((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
|
||||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit) ||
|
|
||||||
(up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
|
||||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)) {
|
|
||||||
proc->types.pointer.scroll_dir = hor_en ? LV_DIR_HOR : LV_DIR_VER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If this object don't want to chain the scroll to the parent stop searching*/
|
|
||||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_HOR) == false && hor_en) break;
|
|
||||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_VER) == false && ver_en) break;
|
|
||||||
|
|
||||||
/*Try the parent*/
|
|
||||||
obj_act = lv_obj_get_parent(obj_act);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Use the last candidate*/
|
|
||||||
if(obj_candidate) {
|
|
||||||
proc->types.pointer.scroll_dir = dir_candidate;
|
|
||||||
proc->types.pointer.scroll_obj = obj_candidate;
|
|
||||||
proc->types.pointer.scroll_sum.x = 0;
|
|
||||||
proc->types.pointer.scroll_sum.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj_candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_scroll_limits(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_obj_t * obj = proc->types.pointer.scroll_obj;
|
|
||||||
/*If there no STOP allow scrolling anywhere*/
|
|
||||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ONE) == false) {
|
|
||||||
lv_area_set(&proc->types.pointer.scroll_area, LV_COORD_MIN, LV_COORD_MIN, LV_COORD_MAX, LV_COORD_MAX);
|
|
||||||
}
|
|
||||||
/*With STOP limit the scrolling to the perv and next snap point*/
|
|
||||||
else {
|
|
||||||
switch(lv_obj_get_scroll_snap_y(obj)) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y1 + 1, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y1 - 1, 0);
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y2, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y2, 0);
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER: {
|
|
||||||
lv_coord_t y_mid = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2;
|
|
||||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, y_mid + 1, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, y_mid - 1, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
proc->types.pointer.scroll_area.y1 = LV_COORD_MIN;
|
|
||||||
proc->types.pointer.scroll_area.y2 = LV_COORD_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(lv_obj_get_scroll_snap_x(obj)) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x1, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x1, 0);
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x2, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x2, 0);
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER: {
|
|
||||||
lv_coord_t x_mid = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2;
|
|
||||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, x_mid + 1, LV_COORD_MAX, 0);
|
|
||||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, x_mid - 1, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
proc->types.pointer.scroll_area.x1 = LV_COORD_MIN;
|
|
||||||
proc->types.pointer.scroll_area.x2 = LV_COORD_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Allow scrolling on the edges. It will be reverted to the edge due to snapping anyway*/
|
|
||||||
if(proc->types.pointer.scroll_area.x1 == 0) proc->types.pointer.scroll_area.x1 = LV_COORD_MIN;
|
|
||||||
if(proc->types.pointer.scroll_area.x2 == 0) proc->types.pointer.scroll_area.x2 = LV_COORD_MAX;
|
|
||||||
if(proc->types.pointer.scroll_area.y1 == 0) proc->types.pointer.scroll_area.y1 = LV_COORD_MIN;
|
|
||||||
if(proc->types.pointer.scroll_area.y2 == 0) proc->types.pointer.scroll_area.y2 = LV_COORD_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for snap point in the `min` - `max` range.
|
|
||||||
* @param obj the object on which snap point should be found
|
|
||||||
* @param min ignore snap points smaller than this. (Absolute coordinate)
|
|
||||||
* @param max ignore snap points greater than this. (Absolute coordinate)
|
|
||||||
* @param ofs offset to snap points. Useful the get a snap point in an imagined case
|
|
||||||
* what if children are already moved by this value
|
|
||||||
* @return the distance of the snap point.
|
|
||||||
*/
|
|
||||||
static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
|
||||||
{
|
|
||||||
lv_scroll_snap_t align = lv_obj_get_scroll_snap_x(obj);
|
|
||||||
if(align == LV_SCROLL_SNAP_NONE) return 0;
|
|
||||||
|
|
||||||
lv_coord_t dist = LV_COORD_MAX;
|
|
||||||
|
|
||||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
|
||||||
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPPABLE)) {
|
|
||||||
lv_coord_t x_child = 0;
|
|
||||||
lv_coord_t x_parent = 0;
|
|
||||||
switch(align) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
x_child = child->coords.x1;
|
|
||||||
x_parent = obj->coords.x1 + pad_left;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
x_child = child->coords.x2;
|
|
||||||
x_parent = obj->coords.x2 - pad_right;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
x_child = child->coords.x1 + lv_area_get_width(&child->coords) / 2;
|
|
||||||
x_parent = obj->coords.x1 + pad_left + (lv_area_get_width(&obj->coords) - pad_left - pad_right) / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
x_child += ofs;
|
|
||||||
if(x_child >= min && x_child <= max) {
|
|
||||||
lv_coord_t x = x_child - x_parent;
|
|
||||||
if(LV_ABS(x) < LV_ABS(dist)) dist = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist == LV_COORD_MAX ? 0 : -dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for snap point in the `min` - `max` range.
|
|
||||||
* @param obj the object on which snap point should be found
|
|
||||||
* @param min ignore snap points smaller than this. (Absolute coordinate)
|
|
||||||
* @param max ignore snap points greater than this. (Absolute coordinate)
|
|
||||||
* @param ofs offset to snap points. Useful to get a snap point in an imagined case
|
|
||||||
* what if children are already moved by this value
|
|
||||||
* @return the distance of the snap point.
|
|
||||||
*/
|
|
||||||
static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
|
||||||
{
|
|
||||||
lv_scroll_snap_t align = lv_obj_get_scroll_snap_y(obj);
|
|
||||||
if(align == LV_SCROLL_SNAP_NONE) return 0;
|
|
||||||
|
|
||||||
lv_coord_t dist = LV_COORD_MAX;
|
|
||||||
|
|
||||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
|
||||||
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPPABLE)) {
|
|
||||||
lv_coord_t y_child = 0;
|
|
||||||
lv_coord_t y_parent = 0;
|
|
||||||
switch(align) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
y_child = child->coords.y1;
|
|
||||||
y_parent = obj->coords.y1 + pad_top;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
y_child = child->coords.y2;
|
|
||||||
y_parent = obj->coords.y2 - pad_bottom;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
y_child = child->coords.y1 + lv_area_get_height(&child->coords) / 2;
|
|
||||||
y_parent = obj->coords.y1 + pad_top + (lv_area_get_height(&obj->coords) - pad_top - pad_bottom) / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
y_child += ofs;
|
|
||||||
if(y_child >= min && y_child <= max) {
|
|
||||||
lv_coord_t y = y_child - y_parent;
|
|
||||||
if(LV_ABS(y) < LV_ABS(dist)) dist = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist == LV_COORD_MAX ? 0 : -dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scroll_limit_diff(_lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y)
|
|
||||||
{
|
|
||||||
if(diff_y) {
|
|
||||||
if(proc->types.pointer.scroll_sum.y + *diff_y < proc->types.pointer.scroll_area.y1) {
|
|
||||||
*diff_y = proc->types.pointer.scroll_area.y1 - proc->types.pointer.scroll_sum.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(proc->types.pointer.scroll_sum.y + *diff_y > proc->types.pointer.scroll_area.y2) {
|
|
||||||
*diff_y = proc->types.pointer.scroll_area.y2 - proc->types.pointer.scroll_sum.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(diff_x) {
|
|
||||||
if(proc->types.pointer.scroll_sum.x + *diff_x < proc->types.pointer.scroll_area.x1) {
|
|
||||||
*diff_x = proc->types.pointer.scroll_area.x1 - proc->types.pointer.scroll_sum.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(proc->types.pointer.scroll_sum.x + *diff_x > proc->types.pointer.scroll_area.x2) {
|
|
||||||
*diff_x = proc->types.pointer.scroll_area.x2 - proc->types.pointer.scroll_sum.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static lv_coord_t scroll_throw_predict_y(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_coord_t y = proc->types.pointer.scroll_throw_vect.y;
|
|
||||||
lv_coord_t move = 0;
|
|
||||||
|
|
||||||
lv_indev_t * indev_act = lv_indev_get_act();
|
|
||||||
lv_coord_t scroll_throw = indev_act->driver->scroll_throw;
|
|
||||||
|
|
||||||
while(y) {
|
|
||||||
move += y;
|
|
||||||
y = y * (100 - scroll_throw) / 100;
|
|
||||||
}
|
|
||||||
return move;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static lv_coord_t scroll_throw_predict_x(_lv_indev_proc_t * proc)
|
|
||||||
{
|
|
||||||
lv_coord_t x = proc->types.pointer.scroll_throw_vect.x;
|
|
||||||
lv_coord_t move = 0;
|
|
||||||
|
|
||||||
lv_indev_t * indev_act = lv_indev_get_act();
|
|
||||||
lv_coord_t scroll_throw = indev_act->driver->scroll_throw;
|
|
||||||
|
|
||||||
while(x) {
|
|
||||||
move += x;
|
|
||||||
x = x * (100 - scroll_throw) / 100;
|
|
||||||
}
|
|
||||||
return move;
|
|
||||||
}
|
|
||||||
|
|
||||||
static lv_coord_t elastic_diff(lv_obj_t * scroll_obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end,
|
|
||||||
lv_dir_t dir)
|
|
||||||
{
|
|
||||||
if(lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_ELASTIC)) {
|
|
||||||
/*If there is snapping in the current direction don't use the elastic factor because
|
|
||||||
*it's natural that the first and last items are scrolled (snapped) in.*/
|
|
||||||
lv_scroll_snap_t snap;
|
|
||||||
snap = dir == LV_DIR_HOR ? lv_obj_get_scroll_snap_x(scroll_obj) : lv_obj_get_scroll_snap_y(scroll_obj);
|
|
||||||
|
|
||||||
lv_obj_t * act_obj = lv_indev_get_obj_act();
|
|
||||||
lv_coord_t snap_point = 0;
|
|
||||||
lv_coord_t act_obj_point = 0;
|
|
||||||
|
|
||||||
if(dir == LV_DIR_HOR) {
|
|
||||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(scroll_obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(scroll_obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
switch(snap) {
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
snap_point = pad_left + (lv_area_get_width(&scroll_obj->coords) - pad_left - pad_right) / 2 + scroll_obj->coords.x1;
|
|
||||||
act_obj_point = lv_area_get_width(&act_obj->coords) / 2 + act_obj->coords.x1;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
snap_point = scroll_obj->coords.x1 + pad_left;
|
|
||||||
act_obj_point = act_obj->coords.x1;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
snap_point = scroll_obj->coords.x2 - pad_right;
|
|
||||||
act_obj_point = act_obj->coords.x2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(scroll_obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(scroll_obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
switch(snap) {
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
snap_point = pad_top + (lv_area_get_height(&scroll_obj->coords) - pad_top - pad_bottom) / 2 + scroll_obj->coords.y1;
|
|
||||||
act_obj_point = lv_area_get_height(&act_obj->coords) / 2 + act_obj->coords.y1;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
snap_point = scroll_obj->coords.y1 + pad_top;
|
|
||||||
act_obj_point = act_obj->coords.y1;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
snap_point = scroll_obj->coords.y2 - pad_bottom;
|
|
||||||
act_obj_point = act_obj->coords.y2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(scroll_end < 0) {
|
|
||||||
if(snap != LV_SCROLL_SNAP_NONE && act_obj_point > snap_point) return diff;
|
|
||||||
|
|
||||||
/*Rounding*/
|
|
||||||
if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2;
|
|
||||||
if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2;
|
|
||||||
return diff / ELASTIC_SLOWNESS_FACTOR;
|
|
||||||
}
|
|
||||||
else if(scroll_start < 0) {
|
|
||||||
if(snap != LV_SCROLL_SNAP_NONE && act_obj_point < snap_point) return diff;
|
|
||||||
|
|
||||||
/*Rounding*/
|
|
||||||
if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2;
|
|
||||||
if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2;
|
|
||||||
return diff / ELASTIC_SLOWNESS_FACTOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Scroll back to the boundary if required*/
|
|
||||||
if(scroll_end + diff < 0) diff = - scroll_end;
|
|
||||||
if(scroll_start - diff < 0) diff = scroll_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_indev_scroll.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_INDEV_SCROLL_H
|
|
||||||
#define LV_INDEV_SCROLL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle scrolling. Called by LVGL during input device processing
|
|
||||||
* @param proc pointer to an input device's proc field
|
|
||||||
*/
|
|
||||||
void _lv_indev_scroll_handler(_lv_indev_proc_t * proc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle throwing after scrolling. Called by LVGL during input device processing
|
|
||||||
* @param proc pointer to an input device's proc field
|
|
||||||
*/
|
|
||||||
void _lv_indev_scroll_throw_handler(_lv_indev_proc_t * proc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Predict where would a scroll throw end
|
|
||||||
* @param indev pointer to an input device
|
|
||||||
* @param dir ` LV_DIR_VER` or `LV_DIR_HOR`
|
|
||||||
* @return the difference compared to the current position when the throw would be finished
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_indev_scroll_throw_predict(lv_indev_t * indev, lv_dir_t dir);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the distance of the nearest snap point
|
|
||||||
* @param obj the object on which snap points should be found
|
|
||||||
* @param p save the distance of the found snap point there
|
|
||||||
*/
|
|
||||||
void lv_indev_scroll_get_snap_dist(lv_obj_t * obj, lv_point_t * p);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_INDEV_SCROLL_H*/
|
|
@ -1,948 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_indev.h"
|
|
||||||
#include "lv_refr.h"
|
|
||||||
#include "lv_group.h"
|
|
||||||
#include "lv_disp.h"
|
|
||||||
#include "lv_theme.h"
|
|
||||||
#include "../misc/lv_assert.h"
|
|
||||||
#include "../draw/lv_draw.h"
|
|
||||||
#include "../misc/lv_anim.h"
|
|
||||||
#include "../misc/lv_timer.h"
|
|
||||||
#include "../misc/lv_async.h"
|
|
||||||
#include "../misc/lv_fs.h"
|
|
||||||
#include "../misc/lv_gc.h"
|
|
||||||
#include "../misc/lv_math.h"
|
|
||||||
#include "../misc/lv_log.h"
|
|
||||||
#include "../hal/lv_hal.h"
|
|
||||||
#include "../extra/lv_extra.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if LV_USE_GPU_STM32_DMA2D
|
|
||||||
#include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_GPU_SWM341_DMA2D
|
|
||||||
#include "../draw/swm341_dma2d/lv_gpu_swm341_dma2d.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
|
|
||||||
#include "../draw/nxp/pxp/lv_gpu_nxp_pxp.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
#define LV_OBJ_DEF_WIDTH (LV_DPX(100))
|
|
||||||
#define LV_OBJ_DEF_HEIGHT (LV_DPX(50))
|
|
||||||
#define STYLE_TRANSITION_MAX 32
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void lv_obj_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
|
||||||
static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
|
||||||
static void lv_obj_draw(lv_event_t * e);
|
|
||||||
static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
|
||||||
static void draw_scrollbar(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx);
|
|
||||||
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc);
|
|
||||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
|
|
||||||
static void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static bool lv_initialized = false;
|
|
||||||
const lv_obj_class_t lv_obj_class = {
|
|
||||||
.constructor_cb = lv_obj_constructor,
|
|
||||||
.destructor_cb = lv_obj_destructor,
|
|
||||||
.event_cb = lv_obj_event,
|
|
||||||
.width_def = LV_DPI_DEF,
|
|
||||||
.height_def = LV_DPI_DEF,
|
|
||||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
|
||||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
|
||||||
.instance_size = (sizeof(lv_obj_t)),
|
|
||||||
.base_class = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
bool lv_is_initialized(void)
|
|
||||||
{
|
|
||||||
return lv_initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_init(void)
|
|
||||||
{
|
|
||||||
/*Do nothing if already initialized*/
|
|
||||||
if(lv_initialized) {
|
|
||||||
LV_LOG_WARN("lv_init: already inited");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_LOG_INFO("begin");
|
|
||||||
|
|
||||||
/*Initialize the misc modules*/
|
|
||||||
lv_mem_init();
|
|
||||||
|
|
||||||
_lv_timer_core_init();
|
|
||||||
|
|
||||||
_lv_fs_init();
|
|
||||||
|
|
||||||
_lv_anim_core_init();
|
|
||||||
|
|
||||||
_lv_group_init();
|
|
||||||
|
|
||||||
lv_draw_init();
|
|
||||||
|
|
||||||
#if LV_USE_GPU_STM32_DMA2D
|
|
||||||
/*Initialize DMA2D GPU*/
|
|
||||||
lv_draw_stm32_dma2d_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_GPU_SWM341_DMA2D
|
|
||||||
/*Initialize DMA2D GPU*/
|
|
||||||
lv_draw_swm341_dma2d_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
|
|
||||||
PXP_COND_STOP(!lv_gpu_nxp_pxp_init(), "PXP init failed.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_lv_obj_style_init();
|
|
||||||
_lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
|
|
||||||
_lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));
|
|
||||||
|
|
||||||
/*Initialize the screen refresh system*/
|
|
||||||
_lv_refr_init();
|
|
||||||
|
|
||||||
_lv_img_decoder_init();
|
|
||||||
#if LV_IMG_CACHE_DEF_SIZE
|
|
||||||
lv_img_cache_set_size(LV_IMG_CACHE_DEF_SIZE);
|
|
||||||
#endif
|
|
||||||
/*Test if the IDE has UTF-8 encoding*/
|
|
||||||
char * txt = "Á";
|
|
||||||
|
|
||||||
uint8_t * txt_u8 = (uint8_t *)txt;
|
|
||||||
if(txt_u8[0] != 0xc3 || txt_u8[1] != 0x81 || txt_u8[2] != 0x00) {
|
|
||||||
LV_LOG_WARN("The strings have no UTF-8 encoding. Non-ASCII characters won't be displayed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t endianess_test = 0x11223344;
|
|
||||||
uint8_t * endianess_test_p = (uint8_t *) &endianess_test;
|
|
||||||
bool big_endian = endianess_test_p[0] == 0x11 ? true : false;
|
|
||||||
|
|
||||||
if(big_endian) {
|
|
||||||
LV_ASSERT_MSG(LV_BIG_ENDIAN_SYSTEM == 1,
|
|
||||||
"It's a big endian system but LV_BIG_ENDIAN_SYSTEM is not enabled in lv_conf.h");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LV_ASSERT_MSG(LV_BIG_ENDIAN_SYSTEM == 0,
|
|
||||||
"It's a little endian system but LV_BIG_ENDIAN_SYSTEM is enabled in lv_conf.h");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_USE_ASSERT_MEM_INTEGRITY
|
|
||||||
LV_LOG_WARN("Memory integrity checks are enabled via LV_USE_ASSERT_MEM_INTEGRITY which makes LVGL much slower");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_ASSERT_OBJ
|
|
||||||
LV_LOG_WARN("Object sanity checks are enabled via LV_USE_ASSERT_OBJ which makes LVGL much slower");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_ASSERT_STYLE
|
|
||||||
LV_LOG_WARN("Style sanity checks are enabled that uses more RAM");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_LOG_LEVEL == LV_LOG_LEVEL_TRACE
|
|
||||||
LV_LOG_WARN("Log level is set to 'Trace' which makes LVGL much slower");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_extra_init();
|
|
||||||
|
|
||||||
lv_initialized = true;
|
|
||||||
|
|
||||||
LV_LOG_TRACE("finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
|
||||||
|
|
||||||
void lv_deinit(void)
|
|
||||||
{
|
|
||||||
_lv_gc_clear_roots();
|
|
||||||
|
|
||||||
lv_disp_set_default(NULL);
|
|
||||||
lv_mem_deinit();
|
|
||||||
lv_initialized = false;
|
|
||||||
|
|
||||||
LV_LOG_INFO("lv_deinit done");
|
|
||||||
|
|
||||||
#if LV_USE_LOG
|
|
||||||
lv_log_register_print_cb(NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_obj_t * lv_obj_create(lv_obj_t * parent)
|
|
||||||
{
|
|
||||||
LV_LOG_INFO("begin");
|
|
||||||
lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
|
|
||||||
lv_obj_class_init_obj(obj);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Setter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/*-----------------
|
|
||||||
* Attribute set
|
|
||||||
*----------------*/
|
|
||||||
|
|
||||||
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
bool was_on_layout = lv_obj_is_layout_positioned(obj);
|
|
||||||
|
|
||||||
if(f & LV_OBJ_FLAG_HIDDEN) lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
obj->flags |= f;
|
|
||||||
|
|
||||||
if(f & LV_OBJ_FLAG_HIDDEN) {
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
|
||||||
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(f & LV_OBJ_FLAG_SCROLLABLE) {
|
|
||||||
lv_area_t hor_area, ver_area;
|
|
||||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
|
||||||
lv_obj_invalidate_area(obj, &hor_area);
|
|
||||||
lv_obj_invalidate_area(obj, &ver_area);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
bool was_on_layout = lv_obj_is_layout_positioned(obj);
|
|
||||||
if(f & LV_OBJ_FLAG_SCROLLABLE) {
|
|
||||||
lv_area_t hor_area, ver_area;
|
|
||||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
|
||||||
lv_obj_invalidate_area(obj, &hor_area);
|
|
||||||
lv_obj_invalidate_area(obj, &ver_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->flags &= (~f);
|
|
||||||
|
|
||||||
if(f & LV_OBJ_FLAG_HIDDEN) {
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
if(lv_obj_is_layout_positioned(obj)) {
|
|
||||||
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
|
||||||
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_state_t new_state = obj->state | state;
|
|
||||||
if(obj->state != new_state) {
|
|
||||||
lv_obj_set_state(obj, new_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_state_t new_state = obj->state & (~state);
|
|
||||||
if(obj->state != new_state) {
|
|
||||||
lv_obj_set_state(obj, new_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=======================
|
|
||||||
* Getter functions
|
|
||||||
*======================*/
|
|
||||||
|
|
||||||
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
return (obj->flags & f) == f ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
return (obj->flags & f) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_state_t lv_obj_get_state(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
return obj->state;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
return obj->state & state ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * lv_obj_get_group(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->group_p;
|
|
||||||
else return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------
|
|
||||||
* OTHER FUNCTIONS
|
|
||||||
*------------------*/
|
|
||||||
|
|
||||||
void lv_obj_allocate_spec_attr(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(obj->spec_attr == NULL) {
|
|
||||||
static uint32_t x = 0;
|
|
||||||
x++;
|
|
||||||
obj->spec_attr = lv_mem_alloc(sizeof(_lv_obj_spec_attr_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->spec_attr);
|
|
||||||
if(obj->spec_attr == NULL) return;
|
|
||||||
|
|
||||||
lv_memset_00(obj->spec_attr, sizeof(_lv_obj_spec_attr_t));
|
|
||||||
|
|
||||||
obj->spec_attr->scroll_dir = LV_DIR_ALL;
|
|
||||||
obj->spec_attr->scrollbar_mode = LV_SCROLLBAR_MODE_AUTO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)
|
|
||||||
{
|
|
||||||
if(obj == NULL) return false;
|
|
||||||
return obj->class_p == class_p ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p)
|
|
||||||
{
|
|
||||||
const lv_obj_class_t * obj_class = obj->class_p;
|
|
||||||
while(obj_class) {
|
|
||||||
if(obj_class == class_p) return true;
|
|
||||||
obj_class = obj_class->base_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
return obj->class_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_is_valid(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_disp_t * disp = lv_disp_get_next(NULL);
|
|
||||||
while(disp) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < disp->screen_cnt; i++) {
|
|
||||||
if(disp->screens[i] == obj) return true;
|
|
||||||
bool found = obj_valid_child(disp->screens[i], obj);
|
|
||||||
if(found) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
disp = lv_disp_get_next(disp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void lv_obj_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_UNUSED(class_p);
|
|
||||||
LV_TRACE_OBJ_CREATE("begin");
|
|
||||||
|
|
||||||
lv_obj_t * parent = obj->parent;
|
|
||||||
if(parent) {
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(parent);
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(parent);
|
|
||||||
|
|
||||||
obj->coords.y1 = parent->coords.y1 + lv_obj_get_style_pad_top(parent, LV_PART_MAIN) - st;
|
|
||||||
obj->coords.y2 = obj->coords.y1 - 1;
|
|
||||||
obj->coords.x1 = parent->coords.x1 + lv_obj_get_style_pad_left(parent, LV_PART_MAIN) - sl;
|
|
||||||
obj->coords.x2 = obj->coords.x1 - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Set attributes*/
|
|
||||||
obj->flags = LV_OBJ_FLAG_CLICKABLE;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_SNAPPABLE;
|
|
||||||
if(parent) obj->flags |= LV_OBJ_FLAG_PRESS_LOCK;
|
|
||||||
if(parent) obj->flags |= LV_OBJ_FLAG_SCROLL_CHAIN;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_CLICK_FOCUSABLE;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_SCROLLABLE;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_SCROLL_ELASTIC;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM;
|
|
||||||
obj->flags |= LV_OBJ_FLAG_SCROLL_WITH_ARROW;
|
|
||||||
if(parent) obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE;
|
|
||||||
|
|
||||||
LV_TRACE_OBJ_CREATE("finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_UNUSED(class_p);
|
|
||||||
|
|
||||||
_lv_event_mark_deleted(obj);
|
|
||||||
|
|
||||||
/*Remove all style*/
|
|
||||||
lv_obj_enable_style_refresh(false); /*No need to refresh the style because the object will be deleted*/
|
|
||||||
lv_obj_remove_style_all(obj);
|
|
||||||
lv_obj_enable_style_refresh(true);
|
|
||||||
|
|
||||||
/*Remove the animations from this object*/
|
|
||||||
lv_anim_del(obj, NULL);
|
|
||||||
|
|
||||||
/*Delete from the group*/
|
|
||||||
lv_group_t * group = lv_obj_get_group(obj);
|
|
||||||
if(group) lv_group_remove_obj(obj);
|
|
||||||
|
|
||||||
if(obj->spec_attr) {
|
|
||||||
if(obj->spec_attr->children) {
|
|
||||||
lv_mem_free(obj->spec_attr->children);
|
|
||||||
obj->spec_attr->children = NULL;
|
|
||||||
}
|
|
||||||
if(obj->spec_attr->event_dsc) {
|
|
||||||
lv_mem_free(obj->spec_attr->event_dsc);
|
|
||||||
obj->spec_attr->event_dsc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_mem_free(obj->spec_attr);
|
|
||||||
obj->spec_attr = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lv_obj_draw(lv_event_t * e)
|
|
||||||
{
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * obj = lv_event_get_target(e);
|
|
||||||
if(code == LV_EVENT_COVER_CHECK) {
|
|
||||||
lv_cover_check_info_t * info = lv_event_get_param(e);
|
|
||||||
if(info->res == LV_COVER_RES_MASKED) return;
|
|
||||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
|
||||||
info->res = LV_COVER_RES_MASKED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Most trivial test. Is the mask fully IN the object? If no it surely doesn't cover it*/
|
|
||||||
lv_coord_t r = lv_obj_get_style_radius(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t w = lv_obj_get_style_transform_width(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t h = lv_obj_get_style_transform_height(obj, LV_PART_MAIN);
|
|
||||||
lv_area_t coords;
|
|
||||||
lv_area_copy(&coords, &obj->coords);
|
|
||||||
coords.x1 -= w;
|
|
||||||
coords.x2 += w;
|
|
||||||
coords.y1 -= h;
|
|
||||||
coords.y2 += h;
|
|
||||||
|
|
||||||
if(_lv_area_is_in(info->area, &coords, r) == false) {
|
|
||||||
info->res = LV_COVER_RES_NOT_COVER;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lv_obj_get_style_bg_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) {
|
|
||||||
info->res = LV_COVER_RES_NOT_COVER;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->res = LV_COVER_RES_COVER;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_DRAW_MAIN) {
|
|
||||||
lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
|
|
||||||
lv_draw_rect_dsc_t draw_dsc;
|
|
||||||
lv_draw_rect_dsc_init(&draw_dsc);
|
|
||||||
/*If the border is drawn later disable loading its properties*/
|
|
||||||
if(lv_obj_get_style_border_post(obj, LV_PART_MAIN)) {
|
|
||||||
draw_dsc.border_post = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc);
|
|
||||||
lv_coord_t w = lv_obj_get_style_transform_width(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t h = lv_obj_get_style_transform_height(obj, LV_PART_MAIN);
|
|
||||||
lv_area_t coords;
|
|
||||||
lv_area_copy(&coords, &obj->coords);
|
|
||||||
coords.x1 -= w;
|
|
||||||
coords.x2 += w;
|
|
||||||
coords.y1 -= h;
|
|
||||||
coords.y2 += h;
|
|
||||||
|
|
||||||
lv_obj_draw_part_dsc_t part_dsc;
|
|
||||||
lv_obj_draw_dsc_init(&part_dsc, draw_ctx);
|
|
||||||
part_dsc.class_p = MY_CLASS;
|
|
||||||
part_dsc.type = LV_OBJ_DRAW_PART_RECTANGLE;
|
|
||||||
part_dsc.rect_dsc = &draw_dsc;
|
|
||||||
part_dsc.draw_area = &coords;
|
|
||||||
part_dsc.part = LV_PART_MAIN;
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
/*With clip corner enabled draw the bg img separately to make it clipped*/
|
|
||||||
bool clip_corner = (lv_obj_get_style_clip_corner(obj, LV_PART_MAIN) && draw_dsc.radius != 0) ? true : false;
|
|
||||||
const void * bg_img_src = draw_dsc.bg_img_src;
|
|
||||||
if(clip_corner) {
|
|
||||||
draw_dsc.bg_img_src = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc, &coords);
|
|
||||||
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(clip_corner) {
|
|
||||||
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
|
|
||||||
lv_draw_mask_radius_init(mp, &obj->coords, draw_dsc.radius, false);
|
|
||||||
/*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/
|
|
||||||
lv_draw_mask_add(mp, obj + 8);
|
|
||||||
|
|
||||||
if(bg_img_src) {
|
|
||||||
draw_dsc.bg_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.border_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.outline_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.shadow_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.bg_img_src = bg_img_src;
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc, &coords);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_DRAW_POST) {
|
|
||||||
lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
|
|
||||||
draw_scrollbar(obj, draw_ctx);
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
|
||||||
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8);
|
|
||||||
if(param) {
|
|
||||||
lv_draw_mask_free_param(param);
|
|
||||||
lv_mem_buf_release(param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*If the border is drawn later disable loading other properties*/
|
|
||||||
if(lv_obj_get_style_border_post(obj, LV_PART_MAIN)) {
|
|
||||||
lv_draw_rect_dsc_t draw_dsc;
|
|
||||||
lv_draw_rect_dsc_init(&draw_dsc);
|
|
||||||
draw_dsc.bg_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.bg_img_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.outline_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc.shadow_opa = LV_OPA_TRANSP;
|
|
||||||
lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc);
|
|
||||||
|
|
||||||
lv_coord_t w = lv_obj_get_style_transform_width(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t h = lv_obj_get_style_transform_height(obj, LV_PART_MAIN);
|
|
||||||
lv_area_t coords;
|
|
||||||
lv_area_copy(&coords, &obj->coords);
|
|
||||||
coords.x1 -= w;
|
|
||||||
coords.x2 += w;
|
|
||||||
coords.y1 -= h;
|
|
||||||
coords.y2 += h;
|
|
||||||
|
|
||||||
lv_obj_draw_part_dsc_t part_dsc;
|
|
||||||
lv_obj_draw_dsc_init(&part_dsc, draw_ctx);
|
|
||||||
part_dsc.class_p = MY_CLASS;
|
|
||||||
part_dsc.type = LV_OBJ_DRAW_PART_BORDER_POST;
|
|
||||||
part_dsc.rect_dsc = &draw_dsc;
|
|
||||||
part_dsc.draw_area = &coords;
|
|
||||||
part_dsc.part = LV_PART_MAIN;
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
|
||||||
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc, &coords);
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_scrollbar(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx)
|
|
||||||
{
|
|
||||||
|
|
||||||
lv_area_t hor_area;
|
|
||||||
lv_area_t ver_area;
|
|
||||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
|
||||||
|
|
||||||
if(lv_area_get_size(&hor_area) <= 0 && lv_area_get_size(&ver_area) <= 0) return;
|
|
||||||
|
|
||||||
lv_draw_rect_dsc_t draw_dsc;
|
|
||||||
lv_res_t sb_res = scrollbar_init_draw_dsc(obj, &draw_dsc);
|
|
||||||
if(sb_res != LV_RES_OK) return;
|
|
||||||
|
|
||||||
lv_obj_draw_part_dsc_t part_dsc;
|
|
||||||
lv_obj_draw_dsc_init(&part_dsc, draw_ctx);
|
|
||||||
part_dsc.class_p = MY_CLASS;
|
|
||||||
part_dsc.type = LV_OBJ_DRAW_PART_SCROLLBAR;
|
|
||||||
part_dsc.rect_dsc = &draw_dsc;
|
|
||||||
part_dsc.part = LV_PART_SCROLLBAR;
|
|
||||||
|
|
||||||
if(lv_area_get_size(&hor_area) > 0) {
|
|
||||||
part_dsc.draw_area = &hor_area;
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc, &hor_area);
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
|
||||||
}
|
|
||||||
if(lv_area_get_size(&ver_area) > 0) {
|
|
||||||
part_dsc.draw_area = &ver_area;
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
|
||||||
part_dsc.draw_area = &ver_area;
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc, &ver_area);
|
|
||||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the draw descriptor for the scrollbar
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param dsc the draw descriptor to initialize
|
|
||||||
* @return LV_RES_OK: the scrollbar is visible; LV_RES_INV: the scrollbar is not visible
|
|
||||||
*/
|
|
||||||
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
lv_draw_rect_dsc_init(dsc);
|
|
||||||
dsc->bg_opa = lv_obj_get_style_bg_opa(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(dsc->bg_opa > LV_OPA_MIN) {
|
|
||||||
dsc->bg_color = lv_obj_get_style_bg_color(obj, LV_PART_SCROLLBAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
dsc->border_opa = lv_obj_get_style_border_opa(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(dsc->border_opa > LV_OPA_MIN) {
|
|
||||||
dsc->border_width = lv_obj_get_style_border_width(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(dsc->border_width > 0) {
|
|
||||||
dsc->border_color = lv_obj_get_style_border_color(obj, LV_PART_SCROLLBAR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dsc->border_opa = LV_OPA_TRANSP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(dsc->shadow_opa > LV_OPA_MIN) {
|
|
||||||
dsc->shadow_width = lv_obj_get_style_shadow_width(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(dsc->shadow_width > 0) {
|
|
||||||
dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, LV_PART_SCROLLBAR);
|
|
||||||
dsc->shadow_color = lv_obj_get_style_shadow_color(obj, LV_PART_SCROLLBAR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dsc->shadow_opa = LV_OPA_TRANSP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_opa_t opa = lv_obj_get_style_opa(obj, LV_PART_SCROLLBAR);
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
dsc->bg_opa = (dsc->bg_opa * opa) >> 8;
|
|
||||||
dsc->border_opa = (dsc->bg_opa * opa) >> 8;
|
|
||||||
dsc->shadow_opa = (dsc->bg_opa * opa) >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dsc->bg_opa != LV_OPA_TRANSP || dsc->border_opa != LV_OPA_TRANSP || dsc->shadow_opa != LV_OPA_TRANSP) {
|
|
||||||
dsc->radius = lv_obj_get_style_radius(obj, LV_PART_SCROLLBAR);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return LV_RES_INV;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if(dsc->bg_opa != LV_OPA_TRANSP || dsc->border_opa != LV_OPA_TRANSP) return LV_RES_OK;
|
|
||||||
else return LV_RES_INV;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|
||||||
{
|
|
||||||
LV_UNUSED(class_p);
|
|
||||||
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * obj = lv_event_get_current_target(e);
|
|
||||||
if(code == LV_EVENT_PRESSED) {
|
|
||||||
lv_obj_add_state(obj, LV_STATE_PRESSED);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_RELEASED) {
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_PRESSED);
|
|
||||||
void * param = lv_event_get_param(e);
|
|
||||||
/*Go the checked state if enabled*/
|
|
||||||
if(lv_indev_get_scroll_obj(param) == NULL && lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
|
|
||||||
if(!(lv_obj_get_state(obj) & LV_STATE_CHECKED)) lv_obj_add_state(obj, LV_STATE_CHECKED);
|
|
||||||
else lv_obj_clear_state(obj, LV_STATE_CHECKED);
|
|
||||||
|
|
||||||
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_PRESS_LOST) {
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_PRESSED);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_STYLE_CHANGED) {
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(uint32_t i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
lv_obj_mark_layout_as_dirty(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_KEY) {
|
|
||||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
|
|
||||||
char c = *((char *)lv_event_get_param(e));
|
|
||||||
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
|
|
||||||
lv_obj_add_state(obj, LV_STATE_CHECKED);
|
|
||||||
}
|
|
||||||
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_CHECKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*With Enter LV_EVENT_RELEASED will send VALUE_CHANGE event*/
|
|
||||||
if(c != LV_KEY_ENTER) {
|
|
||||||
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW) && !lv_obj_is_editable(obj)) {
|
|
||||||
/*scroll by keypad or encoder*/
|
|
||||||
lv_anim_enable_t anim_enable = LV_ANIM_OFF;
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
|
||||||
char c = *((char *)lv_event_get_param(e));
|
|
||||||
if(c == LV_KEY_DOWN) {
|
|
||||||
/*use scroll_to_x/y functions to enforce scroll limits*/
|
|
||||||
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) + lv_obj_get_height(obj) / 4, anim_enable);
|
|
||||||
}
|
|
||||||
else if(c == LV_KEY_UP) {
|
|
||||||
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) - lv_obj_get_height(obj) / 4, anim_enable);
|
|
||||||
}
|
|
||||||
else if(c == LV_KEY_RIGHT) {
|
|
||||||
/*If the object can't be scrolled horizontally then scroll it vertically*/
|
|
||||||
if(!((lv_obj_get_scroll_dir(obj) & LV_DIR_HOR) && (sl > 0 || sr > 0)))
|
|
||||||
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) + lv_obj_get_height(obj) / 4, anim_enable);
|
|
||||||
else
|
|
||||||
lv_obj_scroll_to_x(obj, lv_obj_get_scroll_x(obj) + lv_obj_get_width(obj) / 4, anim_enable);
|
|
||||||
}
|
|
||||||
else if(c == LV_KEY_LEFT) {
|
|
||||||
/*If the object can't be scrolled horizontally then scroll it vertically*/
|
|
||||||
if(!((lv_obj_get_scroll_dir(obj) & LV_DIR_HOR) && (sl > 0 || sr > 0)))
|
|
||||||
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) - lv_obj_get_height(obj) / 4, anim_enable);
|
|
||||||
else
|
|
||||||
lv_obj_scroll_to_x(obj, lv_obj_get_scroll_x(obj) - lv_obj_get_width(obj) / 4, anim_enable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_FOCUSED) {
|
|
||||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS)) {
|
|
||||||
lv_obj_scroll_to_view_recursive(obj, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool editing = false;
|
|
||||||
editing = lv_group_get_editing(lv_obj_get_group(obj));
|
|
||||||
lv_state_t state = LV_STATE_FOCUSED;
|
|
||||||
|
|
||||||
/* Use the indev for then indev handler.
|
|
||||||
* But if the obj was focused manually it returns NULL so try to
|
|
||||||
* use the indev from the event*/
|
|
||||||
lv_indev_t * indev = lv_indev_get_act();
|
|
||||||
if(indev == NULL) indev = lv_event_get_indev(e);
|
|
||||||
|
|
||||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
|
||||||
if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) state |= LV_STATE_FOCUS_KEY;
|
|
||||||
if(editing) {
|
|
||||||
state |= LV_STATE_EDITED;
|
|
||||||
lv_obj_add_state(obj, state);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_obj_add_state(obj, state);
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_EDITED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_SCROLL_BEGIN) {
|
|
||||||
lv_obj_add_state(obj, LV_STATE_SCROLLED);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_SCROLL_END) {
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_SCROLLED);
|
|
||||||
if(lv_obj_get_scrollbar_mode(obj) == LV_SCROLLBAR_MODE_ACTIVE) {
|
|
||||||
lv_area_t hor_area, ver_area;
|
|
||||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
|
||||||
lv_obj_invalidate_area(obj, &hor_area);
|
|
||||||
lv_obj_invalidate_area(obj, &ver_area);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_DEFOCUSED) {
|
|
||||||
lv_obj_clear_state(obj, LV_STATE_FOCUSED | LV_STATE_EDITED | LV_STATE_FOCUS_KEY);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_SIZE_CHANGED) {
|
|
||||||
lv_coord_t align = lv_obj_get_style_align(obj, LV_PART_MAIN);
|
|
||||||
uint16_t layout = lv_obj_get_style_layout(obj, LV_PART_MAIN);
|
|
||||||
if(layout || align) {
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
lv_obj_mark_layout_as_dirty(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_CHILD_CHANGED) {
|
|
||||||
lv_coord_t w = lv_obj_get_style_width(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t h = lv_obj_get_style_height(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t align = lv_obj_get_style_align(obj, LV_PART_MAIN);
|
|
||||||
uint16_t layout = lv_obj_get_style_layout(obj, LV_PART_MAIN);
|
|
||||||
if(layout || align || w == LV_SIZE_CONTENT || h == LV_SIZE_CONTENT) {
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
|
|
||||||
lv_coord_t d = lv_obj_calculate_ext_draw_size(obj, LV_PART_MAIN);
|
|
||||||
lv_event_set_ext_draw_size(e, d);
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_DRAW_MAIN || code == LV_EVENT_DRAW_POST || code == LV_EVENT_COVER_CHECK) {
|
|
||||||
lv_obj_draw(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the state (fully overwrite) of an object.
|
|
||||||
* If specified in the styles, transition animations will be started from the previous state to the current.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param state the new state
|
|
||||||
*/
|
|
||||||
static void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state)
|
|
||||||
{
|
|
||||||
if(obj->state == new_state) return;
|
|
||||||
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_state_t prev_state = obj->state;
|
|
||||||
obj->state = new_state;
|
|
||||||
|
|
||||||
_lv_style_state_cmp_t cmp_res = _lv_obj_style_state_compare(obj, prev_state, new_state);
|
|
||||||
/*If there is no difference in styles there is nothing else to do*/
|
|
||||||
if(cmp_res == _LV_STYLE_STATE_CMP_SAME) return;
|
|
||||||
|
|
||||||
_lv_obj_style_transition_dsc_t * ts = lv_mem_buf_get(sizeof(_lv_obj_style_transition_dsc_t) * STYLE_TRANSITION_MAX);
|
|
||||||
lv_memset_00(ts, sizeof(_lv_obj_style_transition_dsc_t) * STYLE_TRANSITION_MAX);
|
|
||||||
uint32_t tsi = 0;
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt && tsi < STYLE_TRANSITION_MAX; i++) {
|
|
||||||
_lv_obj_style_t * obj_style = &obj->styles[i];
|
|
||||||
lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector);
|
|
||||||
lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector);
|
|
||||||
if(state_act & (~new_state)) continue; /*Skip unrelated styles*/
|
|
||||||
if(obj_style->is_trans) continue;
|
|
||||||
|
|
||||||
lv_style_value_t v;
|
|
||||||
if(lv_style_get_prop_inlined(obj_style->style, LV_STYLE_TRANSITION, &v) != LV_STYLE_RES_FOUND) continue;
|
|
||||||
const lv_style_transition_dsc_t * tr = v.ptr;
|
|
||||||
|
|
||||||
/*Add the props to the set if not added yet or added but with smaller weight*/
|
|
||||||
uint32_t j;
|
|
||||||
for(j = 0; tr->props[j] != 0 && tsi < STYLE_TRANSITION_MAX; j++) {
|
|
||||||
uint32_t t;
|
|
||||||
for(t = 0; t < tsi; t++) {
|
|
||||||
lv_style_selector_t selector = ts[t].selector;
|
|
||||||
lv_state_t state_ts = lv_obj_style_get_selector_state(selector);
|
|
||||||
lv_part_t part_ts = lv_obj_style_get_selector_part(selector);
|
|
||||||
if(ts[t].prop == tr->props[j] && part_ts == part_act && state_ts >= state_act) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*If not found add it*/
|
|
||||||
if(t == tsi) {
|
|
||||||
ts[tsi].time = tr->time;
|
|
||||||
ts[tsi].delay = tr->delay;
|
|
||||||
ts[tsi].path_cb = tr->path_xcb;
|
|
||||||
ts[tsi].prop = tr->props[j];
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
ts[tsi].user_data = tr->user_data;
|
|
||||||
#endif
|
|
||||||
ts[tsi].selector = obj_style->selector;
|
|
||||||
tsi++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < tsi; i++) {
|
|
||||||
lv_part_t part_act = lv_obj_style_get_selector_part(ts[i].selector);
|
|
||||||
_lv_obj_style_create_transition(obj, part_act, prev_state, new_state, &ts[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_mem_buf_release(ts);
|
|
||||||
|
|
||||||
if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_REDRAW) {
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
else if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_LAYOUT) {
|
|
||||||
lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
|
||||||
}
|
|
||||||
else if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD) {
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
lv_obj_refresh_ext_draw_size(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
|
|
||||||
{
|
|
||||||
/*Check all children of `parent`*/
|
|
||||||
uint32_t child_cnt = 0;
|
|
||||||
if(parent->spec_attr) child_cnt = parent->spec_attr->child_cnt;
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = parent->spec_attr->children[i];
|
|
||||||
if(child == obj_to_find) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Check the children*/
|
|
||||||
bool found = obj_valid_child(child, obj_to_find);
|
|
||||||
if(found) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,409 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_H
|
|
||||||
#define LV_OBJ_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../lv_conf_internal.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "../misc/lv_style.h"
|
|
||||||
#include "../misc/lv_types.h"
|
|
||||||
#include "../misc/lv_area.h"
|
|
||||||
#include "../misc/lv_color.h"
|
|
||||||
#include "../misc/lv_assert.h"
|
|
||||||
#include "../hal/lv_hal.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Possible states of a widget.
|
|
||||||
* OR-ed values are possible
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
LV_STATE_DEFAULT = 0x0000,
|
|
||||||
LV_STATE_CHECKED = 0x0001,
|
|
||||||
LV_STATE_FOCUSED = 0x0002,
|
|
||||||
LV_STATE_FOCUS_KEY = 0x0004,
|
|
||||||
LV_STATE_EDITED = 0x0008,
|
|
||||||
LV_STATE_HOVERED = 0x0010,
|
|
||||||
LV_STATE_PRESSED = 0x0020,
|
|
||||||
LV_STATE_SCROLLED = 0x0040,
|
|
||||||
LV_STATE_DISABLED = 0x0080,
|
|
||||||
|
|
||||||
LV_STATE_USER_1 = 0x1000,
|
|
||||||
LV_STATE_USER_2 = 0x2000,
|
|
||||||
LV_STATE_USER_3 = 0x4000,
|
|
||||||
LV_STATE_USER_4 = 0x8000,
|
|
||||||
|
|
||||||
LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef uint16_t lv_state_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The possible parts of widgets.
|
|
||||||
* The parts can be considered as the internal building block of the widgets.
|
|
||||||
* E.g. slider = background + indicator + knob
|
|
||||||
* Not all parts are used by every widget
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
LV_PART_MAIN = 0x000000, /**< A background like rectangle*/
|
|
||||||
LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/
|
|
||||||
LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/
|
|
||||||
LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/
|
|
||||||
LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/
|
|
||||||
LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/
|
|
||||||
LV_PART_TICKS = 0x060000, /**< Ticks on scale e.g. for a chart or meter*/
|
|
||||||
LV_PART_CURSOR = 0x070000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/
|
|
||||||
|
|
||||||
LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/
|
|
||||||
|
|
||||||
LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef uint32_t lv_part_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On/Off features controlling the object's behavior.
|
|
||||||
* OR-ed values are possible
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/
|
|
||||||
LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/
|
|
||||||
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/
|
|
||||||
LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/
|
|
||||||
LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
|
|
||||||
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/
|
|
||||||
LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
|
|
||||||
LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
|
|
||||||
LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
|
|
||||||
LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/
|
|
||||||
LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/
|
|
||||||
LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
|
|
||||||
LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object position-able by the layouts*/
|
|
||||||
LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
|
|
||||||
LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 19), /**< Do not clip the children's content to the parent's boundary*/
|
|
||||||
|
|
||||||
LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
|
|
||||||
LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
|
|
||||||
|
|
||||||
LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/
|
|
||||||
LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/
|
|
||||||
LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/
|
|
||||||
LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/
|
|
||||||
LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/
|
|
||||||
LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32_t lv_obj_flag_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `type` field in `lv_obj_draw_part_dsc_t` if `class_p = lv_obj_class`
|
|
||||||
* Used in `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END`
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
LV_OBJ_DRAW_PART_RECTANGLE, /**< The main rectangle*/
|
|
||||||
LV_OBJ_DRAW_PART_BORDER_POST,/**< The border if style_border_post = true*/
|
|
||||||
LV_OBJ_DRAW_PART_SCROLLBAR, /**< The scrollbar*/
|
|
||||||
} lv_obj_draw_part_type_t;
|
|
||||||
|
|
||||||
#include "lv_obj_tree.h"
|
|
||||||
#include "lv_obj_pos.h"
|
|
||||||
#include "lv_obj_scroll.h"
|
|
||||||
#include "lv_obj_style.h"
|
|
||||||
#include "lv_obj_draw.h"
|
|
||||||
#include "lv_obj_class.h"
|
|
||||||
#include "lv_event.h"
|
|
||||||
#include "lv_group.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make the base object's class publicly available.
|
|
||||||
*/
|
|
||||||
extern const lv_obj_class_t lv_obj_class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Special, rarely used attributes.
|
|
||||||
* They are allocated automatically if any elements is set.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
struct _lv_obj_t ** children; /**< Store the pointer of the children in an array.*/
|
|
||||||
uint32_t child_cnt; /**< Number of children*/
|
|
||||||
lv_group_t * group_p;
|
|
||||||
|
|
||||||
struct _lv_event_dsc_t * event_dsc; /**< Dynamically allocated event callback and user data array*/
|
|
||||||
lv_point_t scroll; /**< The current X/Y scroll offset*/
|
|
||||||
|
|
||||||
lv_coord_t ext_click_pad; /**< Extra click padding in all direction*/
|
|
||||||
lv_coord_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/
|
|
||||||
|
|
||||||
lv_scrollbar_mode_t scrollbar_mode : 2; /**< How to display scrollbars*/
|
|
||||||
lv_scroll_snap_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally*/
|
|
||||||
lv_scroll_snap_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/
|
|
||||||
lv_dir_t scroll_dir : 4; /**< The allowed scroll direction(s)*/
|
|
||||||
uint8_t event_dsc_cnt : 6; /**< Number of event callbacks stored in `event_dsc` array*/
|
|
||||||
uint8_t layer_type : 2; /**< Cache the layer type here. Element of @lv_intermediate_layer_type_t */
|
|
||||||
} _lv_obj_spec_attr_t;
|
|
||||||
|
|
||||||
typedef struct _lv_obj_t {
|
|
||||||
const lv_obj_class_t * class_p;
|
|
||||||
struct _lv_obj_t * parent;
|
|
||||||
_lv_obj_spec_attr_t * spec_attr;
|
|
||||||
_lv_obj_style_t * styles;
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
void * user_data;
|
|
||||||
#endif
|
|
||||||
lv_area_t coords;
|
|
||||||
lv_obj_flag_t flags;
|
|
||||||
lv_state_t state;
|
|
||||||
uint16_t layout_inv : 1;
|
|
||||||
uint16_t scr_layout_inv : 1;
|
|
||||||
uint16_t skip_trans : 1;
|
|
||||||
uint16_t style_cnt : 6;
|
|
||||||
uint16_t h_layout : 1;
|
|
||||||
uint16_t w_layout : 1;
|
|
||||||
} lv_obj_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize LVGL library.
|
|
||||||
* Should be called before any other LVGL related function.
|
|
||||||
*/
|
|
||||||
void lv_init(void);
|
|
||||||
|
|
||||||
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deinit the 'lv' library
|
|
||||||
* Currently only implemented when not using custom allocators, or GC is enabled.
|
|
||||||
*/
|
|
||||||
void lv_deinit(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the 'lv' library is currently initialized
|
|
||||||
*/
|
|
||||||
bool lv_is_initialized(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a base object (a rectangle)
|
|
||||||
* @param parent pointer to a parent object. If NULL then a screen will be created.
|
|
||||||
* @return pointer to the new object
|
|
||||||
*/
|
|
||||||
lv_obj_t * lv_obj_create(lv_obj_t * parent);
|
|
||||||
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Setter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set one or more flags
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param f R-ed values from `lv_obj_flag_t` to set.
|
|
||||||
*/
|
|
||||||
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear one or more flags
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param f OR-ed values from `lv_obj_flag_t` to set.
|
|
||||||
*/
|
|
||||||
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add one or more states to the object. The other state bits will remain unchanged.
|
|
||||||
* If specified in the styles, transition animation will be started from the previous state to the current.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
|
|
||||||
*/
|
|
||||||
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove one or more states to the object. The other state bits will remain unchanged.
|
|
||||||
* If specified in the styles, transition animation will be started from the previous state to the current.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
|
|
||||||
*/
|
|
||||||
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the user_data field of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param user_data pointer to the new user_data.
|
|
||||||
*/
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
static inline void lv_obj_set_user_data(lv_obj_t * obj, void * user_data)
|
|
||||||
{
|
|
||||||
obj->user_data = user_data;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*=======================
|
|
||||||
* Getter functions
|
|
||||||
*======================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a given flag or all the given flags are set on an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param f the flag(s) to check (OR-ed values can be used)
|
|
||||||
* @return true: all flags are set; false: not all flags are set
|
|
||||||
*/
|
|
||||||
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a given flag or any of the flags are set on an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param f the flag(s) to check (OR-ed values can be used)
|
|
||||||
* @return true: at lest one flag flag is set; false: none of the flags are set
|
|
||||||
*/
|
|
||||||
bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the state of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the state (OR-ed values from `lv_state_t`)
|
|
||||||
*/
|
|
||||||
lv_state_t lv_obj_get_state(const lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the object is in a given state or not.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param state a state or combination of states to check
|
|
||||||
* @return true: `obj` is in `state`; false: `obj` is not in `state`
|
|
||||||
*/
|
|
||||||
bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the group of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the pointer to group of the object
|
|
||||||
*/
|
|
||||||
void * lv_obj_get_group(const lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user_data field of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the pointer to the user_data of the object
|
|
||||||
*/
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
static inline void * lv_obj_get_user_data(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
return obj->user_data;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*=======================
|
|
||||||
* Other functions
|
|
||||||
*======================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate special data for an object if not allocated yet.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_allocate_spec_attr(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the type of obj.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param class_p a class to check (e.g. `lv_slider_class`)
|
|
||||||
* @return true: `class_p` is the `obj` class.
|
|
||||||
*/
|
|
||||||
bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if any object has a given class (type).
|
|
||||||
* It checks the ancestor classes too.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param class_p a class to check (e.g. `lv_slider_class`)
|
|
||||||
* @return true: `obj` has the given class
|
|
||||||
*/
|
|
||||||
bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the class (type) of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the class (type) of the object
|
|
||||||
*/
|
|
||||||
const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if any object is still "alive".
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return true: valid
|
|
||||||
*/
|
|
||||||
bool lv_obj_is_valid(const lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale the given number of pixels (a distance or size) relative to a 160 DPI display
|
|
||||||
* considering the DPI of the `obj`'s display.
|
|
||||||
* It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
|
|
||||||
* DPI of the display.
|
|
||||||
* @param obj an object whose display's dpi should be considered
|
|
||||||
* @param n the number of pixels to scale
|
|
||||||
* @return `n x current_dpi/160`
|
|
||||||
*/
|
|
||||||
static inline lv_coord_t lv_obj_dpx(const lv_obj_t * obj, lv_coord_t n)
|
|
||||||
{
|
|
||||||
return _LV_DPX_CALC(lv_disp_get_dpi(lv_obj_get_disp(obj)), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#if LV_USE_ASSERT_OBJ
|
|
||||||
# define LV_ASSERT_OBJ(obj_p, obj_class) \
|
|
||||||
do { \
|
|
||||||
LV_ASSERT_MSG(obj_p != NULL, "The object is NULL"); \
|
|
||||||
LV_ASSERT_MSG(lv_obj_has_class(obj_p, obj_class) == true, "Incompatible object type."); \
|
|
||||||
LV_ASSERT_MSG(lv_obj_is_valid(obj_p) == true, "The object is invalid, deleted or corrupted?"); \
|
|
||||||
} while(0)
|
|
||||||
# else
|
|
||||||
# define LV_ASSERT_OBJ(obj_p, obj_class) do{}while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_LOG && LV_LOG_TRACE_OBJ_CREATE
|
|
||||||
# define LV_TRACE_OBJ_CREATE(...) LV_LOG_TRACE(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
# define LV_TRACE_OBJ_CREATE(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_H*/
|
|
@ -1,202 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_class.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_theme.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void lv_obj_construct(lv_obj_t * obj);
|
|
||||||
static uint32_t get_instance_size(const lv_obj_class_t * class_p);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent)
|
|
||||||
{
|
|
||||||
LV_TRACE_OBJ_CREATE("Creating object with %p class on %p parent", (void *)class_p, (void *)parent);
|
|
||||||
uint32_t s = get_instance_size(class_p);
|
|
||||||
lv_obj_t * obj = lv_mem_alloc(s);
|
|
||||||
if(obj == NULL) return NULL;
|
|
||||||
lv_memset_00(obj, s);
|
|
||||||
obj->class_p = class_p;
|
|
||||||
obj->parent = parent;
|
|
||||||
|
|
||||||
/*Create a screen*/
|
|
||||||
if(parent == NULL) {
|
|
||||||
LV_TRACE_OBJ_CREATE("creating a screen");
|
|
||||||
lv_disp_t * disp = lv_disp_get_default();
|
|
||||||
if(!disp) {
|
|
||||||
LV_LOG_WARN("No display created yet. No place to assign the new screen");
|
|
||||||
lv_mem_free(obj);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(disp->screens == NULL) {
|
|
||||||
disp->screens = lv_mem_alloc(sizeof(lv_obj_t *));
|
|
||||||
disp->screens[0] = obj;
|
|
||||||
disp->screen_cnt = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
disp->screen_cnt++;
|
|
||||||
disp->screens = lv_mem_realloc(disp->screens, sizeof(lv_obj_t *) * disp->screen_cnt);
|
|
||||||
disp->screens[disp->screen_cnt - 1] = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Set coordinates to full screen size*/
|
|
||||||
obj->coords.x1 = 0;
|
|
||||||
obj->coords.y1 = 0;
|
|
||||||
obj->coords.x2 = lv_disp_get_hor_res(NULL) - 1;
|
|
||||||
obj->coords.y2 = lv_disp_get_ver_res(NULL) - 1;
|
|
||||||
}
|
|
||||||
/*Create a normal object*/
|
|
||||||
else {
|
|
||||||
LV_TRACE_OBJ_CREATE("creating normal object");
|
|
||||||
LV_ASSERT_OBJ(parent, MY_CLASS);
|
|
||||||
if(parent->spec_attr == NULL) {
|
|
||||||
lv_obj_allocate_spec_attr(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent->spec_attr->children == NULL) {
|
|
||||||
parent->spec_attr->children = lv_mem_alloc(sizeof(lv_obj_t *));
|
|
||||||
parent->spec_attr->children[0] = obj;
|
|
||||||
parent->spec_attr->child_cnt = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
parent->spec_attr->child_cnt++;
|
|
||||||
parent->spec_attr->children = lv_mem_realloc(parent->spec_attr->children,
|
|
||||||
sizeof(lv_obj_t *) * parent->spec_attr->child_cnt);
|
|
||||||
parent->spec_attr->children[parent->spec_attr->child_cnt - 1] = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_class_init_obj(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
lv_obj_enable_style_refresh(false);
|
|
||||||
|
|
||||||
lv_theme_apply(obj);
|
|
||||||
lv_obj_construct(obj);
|
|
||||||
|
|
||||||
lv_obj_enable_style_refresh(true);
|
|
||||||
lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
|
||||||
|
|
||||||
lv_obj_refresh_self_size(obj);
|
|
||||||
|
|
||||||
lv_group_t * def_group = lv_group_get_default();
|
|
||||||
if(def_group && lv_obj_is_group_def(obj)) {
|
|
||||||
lv_group_add_obj(def_group, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
|
||||||
if(parent) {
|
|
||||||
/*Call the ancestor's event handler to the parent to notify it about the new child.
|
|
||||||
*Also triggers layout update*/
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj);
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CREATED, obj);
|
|
||||||
|
|
||||||
/*Invalidate the area if not screen created*/
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _lv_obj_destruct(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->class_p->destructor_cb) obj->class_p->destructor_cb(obj->class_p, obj);
|
|
||||||
|
|
||||||
if(obj->class_p->base_class) {
|
|
||||||
/*Don't let the descendant methods run during destructing the ancestor type*/
|
|
||||||
obj->class_p = obj->class_p->base_class;
|
|
||||||
|
|
||||||
/*Call the base class's destructor too*/
|
|
||||||
_lv_obj_destruct(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_is_editable(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
const lv_obj_class_t * class_p = obj->class_p;
|
|
||||||
|
|
||||||
/*Find a base in which editable is set*/
|
|
||||||
while(class_p && class_p->editable == LV_OBJ_CLASS_EDITABLE_INHERIT) class_p = class_p->base_class;
|
|
||||||
|
|
||||||
if(class_p == NULL) return false;
|
|
||||||
|
|
||||||
return class_p->editable == LV_OBJ_CLASS_EDITABLE_TRUE ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_is_group_def(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
const lv_obj_class_t * class_p = obj->class_p;
|
|
||||||
|
|
||||||
/*Find a base in which group_def is set*/
|
|
||||||
while(class_p && class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_INHERIT) class_p = class_p->base_class;
|
|
||||||
|
|
||||||
if(class_p == NULL) return false;
|
|
||||||
|
|
||||||
return class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_TRUE ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void lv_obj_construct(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
const lv_obj_class_t * original_class_p = obj->class_p;
|
|
||||||
|
|
||||||
if(obj->class_p->base_class) {
|
|
||||||
/*Don't let the descendant methods run during constructing the ancestor type*/
|
|
||||||
obj->class_p = obj->class_p->base_class;
|
|
||||||
|
|
||||||
/*Construct the base first*/
|
|
||||||
lv_obj_construct(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Restore the original class*/
|
|
||||||
obj->class_p = original_class_p;
|
|
||||||
|
|
||||||
if(obj->class_p->constructor_cb) obj->class_p->constructor_cb(obj->class_p, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t get_instance_size(const lv_obj_class_t * class_p)
|
|
||||||
{
|
|
||||||
/*Find a base in which instance size is set*/
|
|
||||||
const lv_obj_class_t * base = class_p;
|
|
||||||
while(base && base->instance_size == 0) base = base->base_class;
|
|
||||||
|
|
||||||
if(base == NULL) return 0; /*Never happens: set at least in `lv_obj` class*/
|
|
||||||
|
|
||||||
return base->instance_size;
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_class.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_CLASS_H
|
|
||||||
#define LV_OBJ_CLASS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
struct _lv_obj_class_t;
|
|
||||||
struct _lv_event_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_OBJ_CLASS_EDITABLE_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/
|
|
||||||
LV_OBJ_CLASS_EDITABLE_TRUE,
|
|
||||||
LV_OBJ_CLASS_EDITABLE_FALSE,
|
|
||||||
} lv_obj_class_editable_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_OBJ_CLASS_GROUP_DEF_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/
|
|
||||||
LV_OBJ_CLASS_GROUP_DEF_TRUE,
|
|
||||||
LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
|
||||||
} lv_obj_class_group_def_t;
|
|
||||||
|
|
||||||
typedef void (*lv_obj_class_event_cb_t)(struct _lv_obj_class_t * class_p, struct _lv_event_t * e);
|
|
||||||
/**
|
|
||||||
* Describe the common methods of every object.
|
|
||||||
* Similar to a C++ class.
|
|
||||||
*/
|
|
||||||
typedef struct _lv_obj_class_t {
|
|
||||||
const struct _lv_obj_class_t * base_class;
|
|
||||||
void (*constructor_cb)(const struct _lv_obj_class_t * class_p, struct _lv_obj_t * obj);
|
|
||||||
void (*destructor_cb)(const struct _lv_obj_class_t * class_p, struct _lv_obj_t * obj);
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
void * user_data;
|
|
||||||
#endif
|
|
||||||
void (*event_cb)(const struct _lv_obj_class_t * class_p,
|
|
||||||
struct _lv_event_t * e); /**< Widget type specific event function*/
|
|
||||||
lv_coord_t width_def;
|
|
||||||
lv_coord_t height_def;
|
|
||||||
uint32_t editable : 2; /**< Value from ::lv_obj_class_editable_t*/
|
|
||||||
uint32_t group_def : 2; /**< Value from ::lv_obj_class_group_def_t*/
|
|
||||||
uint32_t instance_size : 16;
|
|
||||||
} lv_obj_class_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an object form a class descriptor
|
|
||||||
* @param class_p pointer to a class
|
|
||||||
* @param parent pointer to an object where the new object should be created
|
|
||||||
* @return pointer to the created object
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_obj_class_create_obj(const struct _lv_obj_class_t * class_p, struct _lv_obj_t * parent);
|
|
||||||
|
|
||||||
void lv_obj_class_init_obj(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
void _lv_obj_destruct(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
bool lv_obj_is_editable(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
bool lv_obj_is_group_def(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_CLASS_H*/
|
|
@ -1,406 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_draw.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj_draw.h"
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_disp.h"
|
|
||||||
#include "lv_indev.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
lv_opa_t opa = LV_OPA_COVER;
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
opa = lv_obj_get_style_opa(obj, part);
|
|
||||||
if(opa <= LV_OPA_MIN) {
|
|
||||||
draw_dsc->bg_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc->bg_img_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc->border_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc->outline_opa = LV_OPA_TRANSP;
|
|
||||||
draw_dsc->shadow_opa = LV_OPA_TRANSP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
|
||||||
|
|
||||||
draw_dsc->radius = lv_obj_get_style_radius(obj, part);
|
|
||||||
|
|
||||||
if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
|
|
||||||
if(draw_dsc->bg_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
|
|
||||||
const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part);
|
|
||||||
if(grad && grad->dir != LV_GRAD_DIR_NONE) {
|
|
||||||
lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
draw_dsc->bg_grad.dir = lv_obj_get_style_bg_grad_dir(obj, part);
|
|
||||||
if(draw_dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
|
|
||||||
draw_dsc->bg_grad.stops[0].color = lv_obj_get_style_bg_color_filtered(obj, part);
|
|
||||||
draw_dsc->bg_grad.stops[1].color = lv_obj_get_style_bg_grad_color_filtered(obj, part);
|
|
||||||
draw_dsc->bg_grad.stops[0].frac = lv_obj_get_style_bg_main_stop(obj, part);
|
|
||||||
draw_dsc->bg_grad.stops[1].frac = lv_obj_get_style_bg_grad_stop(obj, part);
|
|
||||||
}
|
|
||||||
draw_dsc->bg_grad.dither = lv_obj_get_style_bg_dither_mode(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
|
|
||||||
if(draw_dsc->border_width) {
|
|
||||||
if(draw_dsc->border_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
|
|
||||||
if(draw_dsc->border_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
|
|
||||||
draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
|
|
||||||
if(draw_dsc->outline_width) {
|
|
||||||
if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
|
||||||
if(draw_dsc->outline_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
|
||||||
draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part);
|
|
||||||
if(draw_dsc->bg_img_src) {
|
|
||||||
draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part);
|
|
||||||
if(draw_dsc->bg_img_opa > LV_OPA_MIN) {
|
|
||||||
if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) {
|
|
||||||
draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part);
|
|
||||||
draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part);
|
|
||||||
draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part);
|
|
||||||
draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(draw_dsc->shadow_opa) {
|
|
||||||
draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
|
|
||||||
if(draw_dsc->shadow_width) {
|
|
||||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part);
|
|
||||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
|
|
||||||
draw_dsc->shadow_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
|
|
||||||
draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part);
|
|
||||||
draw_dsc->shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /*LV_DRAW_COMPLEX*/
|
|
||||||
if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
|
|
||||||
if(draw_dsc->bg_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
|
|
||||||
if(draw_dsc->border_width) {
|
|
||||||
if(draw_dsc->border_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
|
|
||||||
if(draw_dsc->border_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part);
|
|
||||||
draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
|
|
||||||
if(draw_dsc->outline_width) {
|
|
||||||
if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
|
||||||
if(draw_dsc->outline_opa > LV_OPA_MIN) {
|
|
||||||
draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
|
||||||
draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) {
|
|
||||||
draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part);
|
|
||||||
if(draw_dsc->bg_img_src) {
|
|
||||||
draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part);
|
|
||||||
if(draw_dsc->bg_img_opa > LV_OPA_MIN) {
|
|
||||||
if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) {
|
|
||||||
draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part);
|
|
||||||
draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part);
|
|
||||||
draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part);
|
|
||||||
draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
draw_dsc->bg_opa = (opa * draw_dsc->shadow_opa) >> 8;
|
|
||||||
draw_dsc->bg_img_opa = (opa * draw_dsc->shadow_opa) >> 8;
|
|
||||||
draw_dsc->border_opa = (opa * draw_dsc->shadow_opa) >> 8;
|
|
||||||
draw_dsc->outline_opa = (opa * draw_dsc->shadow_opa) >> 8;
|
|
||||||
draw_dsc->shadow_opa = (opa * draw_dsc->shadow_opa) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
draw_dsc->opa = lv_obj_get_style_text_opa(obj, part);
|
|
||||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
lv_opa_t opa = lv_obj_get_style_opa(obj, part);
|
|
||||||
if(opa <= LV_OPA_MIN) {
|
|
||||||
draw_dsc->opa = LV_OPA_TRANSP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->color = lv_obj_get_style_text_color_filtered(obj, part);
|
|
||||||
draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part);
|
|
||||||
draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part);
|
|
||||||
draw_dsc->decor = lv_obj_get_style_text_decor(obj, part);
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
draw_dsc->font = lv_obj_get_style_text_font(obj, part);
|
|
||||||
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
draw_dsc->bidi_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
draw_dsc->align = lv_obj_get_style_text_align(obj, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
draw_dsc->opa = lv_obj_get_style_img_opa(obj, part);
|
|
||||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
lv_opa_t opa = lv_obj_get_style_opa(obj, part);
|
|
||||||
if(opa <= LV_OPA_MIN) {
|
|
||||||
draw_dsc->opa = LV_OPA_TRANSP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->angle = 0;
|
|
||||||
draw_dsc->zoom = LV_IMG_ZOOM_NONE;
|
|
||||||
draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
|
|
||||||
draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
|
|
||||||
|
|
||||||
draw_dsc->recolor_opa = lv_obj_get_style_img_recolor_opa(obj, part);
|
|
||||||
if(draw_dsc->recolor_opa > 0) {
|
|
||||||
draw_dsc->recolor = lv_obj_get_style_img_recolor_filtered(obj, part);
|
|
||||||
}
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
draw_dsc->opa = lv_obj_get_style_line_opa(obj, part);
|
|
||||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
lv_opa_t opa = lv_obj_get_style_opa(obj, part);
|
|
||||||
if(opa <= LV_OPA_MIN) {
|
|
||||||
draw_dsc->opa = LV_OPA_TRANSP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->width = lv_obj_get_style_line_width(obj, part);
|
|
||||||
if(draw_dsc->width == 0) return;
|
|
||||||
|
|
||||||
draw_dsc->color = lv_obj_get_style_line_color_filtered(obj, part);
|
|
||||||
|
|
||||||
draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part);
|
|
||||||
if(draw_dsc->dash_width) {
|
|
||||||
draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part);
|
|
||||||
draw_dsc->round_end = draw_dsc->round_start;
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
draw_dsc->width = lv_obj_get_style_arc_width(obj, part);
|
|
||||||
if(draw_dsc->width == 0) return;
|
|
||||||
|
|
||||||
draw_dsc->opa = lv_obj_get_style_arc_opa(obj, part);
|
|
||||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
if(part != LV_PART_MAIN) {
|
|
||||||
lv_opa_t opa = lv_obj_get_style_opa(obj, part);
|
|
||||||
if(opa <= LV_OPA_MIN) {
|
|
||||||
draw_dsc->opa = LV_OPA_TRANSP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(opa < LV_OPA_MAX) {
|
|
||||||
draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_dsc->color = lv_obj_get_style_arc_color_filtered(obj, part);
|
|
||||||
draw_dsc->img_src = lv_obj_get_style_arc_img_src(obj, part);
|
|
||||||
|
|
||||||
draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part);
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_coord_t s = 0;
|
|
||||||
|
|
||||||
lv_coord_t sh_width = lv_obj_get_style_shadow_width(obj, part);
|
|
||||||
if(sh_width) {
|
|
||||||
lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part);
|
|
||||||
if(sh_opa > LV_OPA_MIN) {
|
|
||||||
sh_width = sh_width / 2 + 1; /*The blur adds only half width*/
|
|
||||||
sh_width += lv_obj_get_style_shadow_spread(obj, part);
|
|
||||||
lv_coord_t sh_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
|
|
||||||
lv_coord_t sh_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
|
|
||||||
sh_width += LV_MAX(LV_ABS(sh_ofs_x), LV_ABS(sh_ofs_y));
|
|
||||||
s = LV_MAX(s, sh_width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t outline_width = lv_obj_get_style_outline_width(obj, part);
|
|
||||||
if(outline_width) {
|
|
||||||
lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
|
||||||
if(outline_opa > LV_OPA_MIN) {
|
|
||||||
lv_coord_t outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
|
||||||
s = LV_MAX(s, outline_pad + outline_width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t w = lv_obj_get_style_transform_width(obj, part);
|
|
||||||
lv_coord_t h = lv_obj_get_style_transform_height(obj, part);
|
|
||||||
lv_coord_t wh = LV_MAX(w, h);
|
|
||||||
if(wh > 0) s += wh;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc, lv_draw_ctx_t * draw_ctx)
|
|
||||||
{
|
|
||||||
lv_memset_00(dsc, sizeof(lv_obj_draw_part_dsc_t));
|
|
||||||
dsc->draw_ctx = draw_ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_draw_part_check_type(lv_obj_draw_part_dsc_t * dsc, const lv_obj_class_t * class_p, uint32_t type)
|
|
||||||
{
|
|
||||||
if(dsc->class_p == class_p && dsc->type == type) return true;
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_refresh_ext_draw_size(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_coord_t s_old = _lv_obj_get_ext_draw_size(obj);
|
|
||||||
lv_coord_t s_new = 0;
|
|
||||||
lv_event_send(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new);
|
|
||||||
|
|
||||||
if(s_new != s_old) lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
/*Store the result if the special attrs already allocated*/
|
|
||||||
if(obj->spec_attr) {
|
|
||||||
obj->spec_attr->ext_draw_size = s_new;
|
|
||||||
}
|
|
||||||
/*Allocate spec. attrs. only if the result is not zero.
|
|
||||||
*Zero is the default value if the spec. attr. are not defined.*/
|
|
||||||
else if(s_new != 0) {
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
obj->spec_attr->ext_draw_size = s_new;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_new != s_old) lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->ext_draw_size;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->layer_type;
|
|
||||||
else return LV_LAYER_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
@ -1,172 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_draw.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_DRAW_H
|
|
||||||
#define LV_OBJ_DRAW_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../draw/lv_draw.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
struct _lv_obj_class_t;
|
|
||||||
|
|
||||||
/** Cover check results.*/
|
|
||||||
typedef enum {
|
|
||||||
LV_COVER_RES_COVER = 0,
|
|
||||||
LV_COVER_RES_NOT_COVER = 1,
|
|
||||||
LV_COVER_RES_MASKED = 2,
|
|
||||||
} lv_cover_res_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_LAYER_TYPE_NONE,
|
|
||||||
LV_LAYER_TYPE_SIMPLE,
|
|
||||||
LV_LAYER_TYPE_TRANSFORM,
|
|
||||||
} lv_layer_type_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lv_draw_ctx_t * draw_ctx; /**< Draw context*/
|
|
||||||
const struct _lv_obj_class_t * class_p; /**< The class that sent the event */
|
|
||||||
uint32_t type; /**< The type if part being draw. Element of `lv_<name>_draw_part_type_t` */
|
|
||||||
lv_area_t * draw_area; /**< The area of the part being drawn*/
|
|
||||||
lv_draw_rect_dsc_t *
|
|
||||||
rect_dsc; /**< A draw descriptor that can be modified to changed what LVGL will draw. Set only for rectangle-like parts*/
|
|
||||||
lv_draw_label_dsc_t *
|
|
||||||
label_dsc; /**< A draw descriptor that can be modified to changed what LVGL will draw. Set only for text-like parts*/
|
|
||||||
lv_draw_line_dsc_t *
|
|
||||||
line_dsc; /**< A draw descriptor that can be modified to changed what LVGL will draw. Set only for line-like parts*/
|
|
||||||
lv_draw_img_dsc_t *
|
|
||||||
img_dsc; /**< A draw descriptor that can be modified to changed what LVGL will draw. Set only for image-like parts*/
|
|
||||||
lv_draw_arc_dsc_t *
|
|
||||||
arc_dsc; /**< A draw descriptor that can be modified to changed what LVGL will draw. Set only for arc-like parts*/
|
|
||||||
const lv_point_t *
|
|
||||||
p1; /**< A point calculated during drawing. E.g. a point of chart or the center of an arc.*/
|
|
||||||
const lv_point_t * p2; /**< A point calculated during drawing. E.g. a point of chart.*/
|
|
||||||
char * text; /**< A text calculated during drawing. Can be modified. E.g. tick labels on a chart axis.*/
|
|
||||||
uint32_t text_length; /**< Size of the text buffer containing null-terminated text string calculated during drawing.*/
|
|
||||||
uint32_t part; /**< The current part for which the event is sent*/
|
|
||||||
uint32_t id; /**< The index of the part. E.g. a button's index on button matrix or table cell index.*/
|
|
||||||
lv_coord_t radius; /**< E.g. the radius of an arc (not the corner radius).*/
|
|
||||||
int32_t value; /**< A value calculated during drawing. E.g. Chart's tick line value.*/
|
|
||||||
const void * sub_part_ptr; /**< A pointer the identifies something in the part. E.g. chart series. */
|
|
||||||
} lv_obj_draw_part_dsc_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a rectangle draw descriptor from an object's styles in its current state
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
|
||||||
* @param draw_dsc the descriptor to initialize.
|
|
||||||
* If an `..._opa` field is set to `LV_OPA_TRANSP` the related properties won't be initialized.
|
|
||||||
* Should be initialized with `lv_draw_rect_dsc_init(draw_dsc)`.
|
|
||||||
* @note Only the relevant fields will be set.
|
|
||||||
* E.g. if `border width == 0` the other border properties won't be evaluated.
|
|
||||||
*/
|
|
||||||
void lv_obj_init_draw_rect_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a label draw descriptor from an object's styles in its current state
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
|
||||||
* @param draw_dsc the descriptor to initialize.
|
|
||||||
* If the `opa` field is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
|
||||||
* Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`.
|
|
||||||
*/
|
|
||||||
void lv_obj_init_draw_label_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize an image draw descriptor from an object's styles in its current state
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
|
||||||
* @param draw_dsc the descriptor to initialize.
|
|
||||||
* Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`.
|
|
||||||
*/
|
|
||||||
void lv_obj_init_draw_img_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a line draw descriptor from an object's styles in its current state
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
|
||||||
* @param draw_dsc the descriptor to initialize.
|
|
||||||
* Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`.
|
|
||||||
*/
|
|
||||||
void lv_obj_init_draw_line_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize an arc draw descriptor from an object's styles in its current state
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
|
||||||
* @param draw_dsc the descriptor to initialize.
|
|
||||||
* Should be initialized with `lv_draw_arc_dsc_init(draw_dsc)`.
|
|
||||||
*/
|
|
||||||
void lv_obj_init_draw_arc_dsc(struct _lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part part of the object
|
|
||||||
* @return the extra size required around the object
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_calculate_ext_draw_size(struct _lv_obj_t * obj, uint32_t part);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a draw descriptor used in events.
|
|
||||||
* @param dsc pointer to a descriptor. Later it should be passed as parameter to an `LV_EVENT_DRAW_PART_BEGIN/END` event.
|
|
||||||
* @param draw the current draw context. (usually returned by `lv_event_get_draw_ctx(e)`)
|
|
||||||
*/
|
|
||||||
void lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc, lv_draw_ctx_t * draw_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the type obj a part draw descriptor
|
|
||||||
* @param dsc the descriptor (normally the event parameter)
|
|
||||||
* @param class_p pointer to class to which `type` is related
|
|
||||||
* @param type element of `lv_<name>_draw_part_type_t`
|
|
||||||
* @return true if ::dsc is related to ::class_p and ::type
|
|
||||||
*/
|
|
||||||
bool lv_obj_draw_part_check_type(lv_obj_draw_part_dsc_t * dsc, const struct _lv_obj_class_t * class_p, uint32_t type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a 'LV_EVENT_REFR_EXT_DRAW_SIZE' Call the ancestor's event handler to the object to refresh the value of the extended draw size.
|
|
||||||
* The result will be saved in `obj`.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_refresh_ext_draw_size(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the extended draw area of an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the size extended draw area around the real coordinates
|
|
||||||
*/
|
|
||||||
lv_coord_t _lv_obj_get_ext_draw_size(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
|
|
||||||
lv_layer_type_t _lv_obj_get_layer_type(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_DRAW_H*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,449 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_pos.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_POS_H
|
|
||||||
#define LV_OBJ_POS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../misc/lv_area.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
struct _lv_obj_t;
|
|
||||||
|
|
||||||
typedef void (*lv_layout_update_cb_t)(struct _lv_obj_t *, void * user_data);
|
|
||||||
typedef struct {
|
|
||||||
lv_layout_update_cb_t cb;
|
|
||||||
void * user_data;
|
|
||||||
} lv_layout_dsc_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the position of an object relative to the set alignment.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param x new x coordinate
|
|
||||||
* @param y new y coordinate
|
|
||||||
* @note With default alignment it's the distance from the top left corner
|
|
||||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
|
||||||
* @note The position is interpreted on the content area of the parent
|
|
||||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the x coordinate of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param x new x coordinate
|
|
||||||
* @note With default alignment it's the distance from the top left corner
|
|
||||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
|
||||||
* @note The position is interpreted on the content area of the parent
|
|
||||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the y coordinate of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param y new y coordinate
|
|
||||||
* @note With default alignment it's the distance from the top left corner
|
|
||||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
|
||||||
* @note The position is interpreted on the content area of the parent
|
|
||||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param w the new width
|
|
||||||
* @param h the new height
|
|
||||||
* @note possible values are:
|
|
||||||
* pixel simple set the size accordingly
|
|
||||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
|
||||||
* LV_SIZE_PCT(x) to set size in percentage of the parent's content area size (the size without paddings).
|
|
||||||
* x should be in [0..1000]% range
|
|
||||||
*/
|
|
||||||
void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recalculate the size of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return true: the size has been changed
|
|
||||||
*/
|
|
||||||
bool lv_obj_refr_size(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the width of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param w the new width
|
|
||||||
* @note possible values are:
|
|
||||||
* pixel simple set the size accordingly
|
|
||||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
|
||||||
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
|
|
||||||
* x should be in [0..1000]% range
|
|
||||||
*/
|
|
||||||
void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the height of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param h the new height
|
|
||||||
* @note possible values are:
|
|
||||||
* pixel simple set the size accordingly
|
|
||||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
|
||||||
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
|
|
||||||
* x should be in [0..1000]% range
|
|
||||||
*/
|
|
||||||
void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the width reduced by the left and right padding and the border width.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param w the width without paddings in pixels
|
|
||||||
*/
|
|
||||||
void lv_obj_set_content_width(struct _lv_obj_t * obj, lv_coord_t w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the height reduced by the top and bottom padding and the border width.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param h the height without paddings in pixels
|
|
||||||
*/
|
|
||||||
void lv_obj_set_content_height(struct _lv_obj_t * obj, lv_coord_t h);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a layout for an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param layout pointer to a layout descriptor to set
|
|
||||||
*/
|
|
||||||
void lv_obj_set_layout(struct _lv_obj_t * obj, uint32_t layout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether the and object is positioned by a layout or not
|
|
||||||
* @param obj pointer to an object to test
|
|
||||||
* @return true: positioned by a layout; false: not positioned by a layout
|
|
||||||
*/
|
|
||||||
bool lv_obj_is_layout_positioned(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the object for layout update.
|
|
||||||
* @param obj pointer to an object whose children needs to be updated
|
|
||||||
*/
|
|
||||||
void lv_obj_mark_layout_as_dirty(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the layout of an object.
|
|
||||||
* @param obj pointer to an object whose children needs to be updated
|
|
||||||
*/
|
|
||||||
void lv_obj_update_layout(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a new layout
|
|
||||||
* @param cb the layout update callback
|
|
||||||
* @param user_data custom data that will be passed to `cb`
|
|
||||||
* @return the ID of the new layout
|
|
||||||
*/
|
|
||||||
uint32_t lv_layout_register(lv_layout_update_cb_t cb, void * user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the alignment of an object.
|
|
||||||
* @param obj pointer to an object to align
|
|
||||||
* @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used.
|
|
||||||
*/
|
|
||||||
void lv_obj_set_align(struct _lv_obj_t * obj, lv_align_t align);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the alignment of an object and set new coordinates.
|
|
||||||
* Equivalent to:
|
|
||||||
* lv_obj_set_align(obj, align);
|
|
||||||
* lv_obj_set_pos(obj, x_ofs, y_ofs);
|
|
||||||
* @param obj pointer to an object to align
|
|
||||||
* @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used.
|
|
||||||
* @param x_ofs x coordinate offset after alignment
|
|
||||||
* @param y_ofs y coordinate offset after alignment
|
|
||||||
*/
|
|
||||||
void lv_obj_align(struct _lv_obj_t * obj, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Align an object to an other object.
|
|
||||||
* @param obj pointer to an object to align
|
|
||||||
* @param base pointer to an other object (if NULL `obj`s parent is used). 'obj' will be aligned to it.
|
|
||||||
* @param align type of alignment (see 'lv_align_t' enum)
|
|
||||||
* @param x_ofs x coordinate offset after alignment
|
|
||||||
* @param y_ofs y coordinate offset after alignment
|
|
||||||
* @note if the position or size of `base` changes `obj` needs to be aligned manually again
|
|
||||||
*/
|
|
||||||
void lv_obj_align_to(struct _lv_obj_t * obj, const struct _lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs,
|
|
||||||
lv_coord_t y_ofs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Align an object to the center on its parent.
|
|
||||||
* @param obj pointer to an object to align
|
|
||||||
* @note if the parent size changes `obj` needs to be aligned manually again
|
|
||||||
*/
|
|
||||||
static inline void lv_obj_center(struct _lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the coordinates of an object to an area
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param coords pointer to an area to store the coordinates
|
|
||||||
*/
|
|
||||||
void lv_obj_get_coords(const struct _lv_obj_t * obj, lv_area_t * coords);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the x coordinate of object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return distance of `obj` from the left side of its parent plus the parent's left padding
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @note Zero return value means the object is on the left padding of the parent, and not on the left edge.
|
|
||||||
* @note Scrolling of the parent doesn't change the returned value.
|
|
||||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_x(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the x2 coordinate of object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return distance of `obj` from the right side of its parent plus the parent's right padding
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @note Zero return value means the object is on the right padding of the parent, and not on the right edge.
|
|
||||||
* @note Scrolling of the parent doesn't change the returned value.
|
|
||||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_x2(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the y coordinate of object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return distance of `obj` from the top side of its parent plus the parent's top padding
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @note Zero return value means the object is on the top padding of the parent, and not on the top edge.
|
|
||||||
* @note Scrolling of the parent doesn't change the returned value.
|
|
||||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_y(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the y2 coordinate of object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return distance of `obj` from the bottom side of its parent plus the parent's bottom padding
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @note Zero return value means the object is on the bottom padding of the parent, and not on the bottom edge.
|
|
||||||
* @note Scrolling of the parent doesn't change the returned value.
|
|
||||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_y2(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the actually set x coordinate of object, i.e. the offset form the set alignment
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the set x coordinate
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_x_aligned(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the actually set y coordinate of object, i.e. the offset form the set alignment
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the set y coordinate
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_y_aligned(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @return the width in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_width(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @return the height in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_height(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width reduced by the left and right padding and the border width.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @return the width which still fits into its parent without causing overflow (making the parent scrollable)
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_content_width(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height reduced by the top and bottom padding and the border width.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @return the height which still fits into the parent without causing overflow (making the parent scrollable)
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_content_height(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the area reduced by the paddings and the border width.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
|
||||||
* call `lv_obj_update_layout(obj)`.
|
|
||||||
* @param area the area which still fits into the parent without causing overflow (making the parent scrollable)
|
|
||||||
*/
|
|
||||||
void lv_obj_get_content_coords(const struct _lv_obj_t * obj, lv_area_t * area);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width occupied by the "parts" of the widget. E.g. the width of all columns of a table.
|
|
||||||
* @param obj pointer to an objects
|
|
||||||
* @return the width of the virtually drawn content
|
|
||||||
* @note This size independent from the real size of the widget.
|
|
||||||
* It just tells how large the internal ("virtual") content is.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_self_width(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height occupied by the "parts" of the widget. E.g. the height of all rows of a table.
|
|
||||||
* @param obj pointer to an objects
|
|
||||||
* @return the width of the virtually drawn content
|
|
||||||
* @note This size independent from the real size of the widget.
|
|
||||||
* It just tells how large the internal ("virtual") content is.
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_self_height(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle if the size of the internal ("virtual") content of an object has changed.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return false: nothing happened; true: refresh happened
|
|
||||||
*/
|
|
||||||
bool lv_obj_refresh_self_size(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
void lv_obj_refr_pos(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
void lv_obj_move_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
|
||||||
|
|
||||||
|
|
||||||
void lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff, bool ignore_floating);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform a point using the angle and zoom style properties of an object
|
|
||||||
* @param obj pointer to an object whose style properties should be used
|
|
||||||
* @param p a point to transform, the result will be written back here too
|
|
||||||
* @param recursive consider the transformation properties of the parents too
|
|
||||||
* @param inv do the inverse of the transformation (-angle and 1/zoom)
|
|
||||||
*/
|
|
||||||
void lv_obj_transform_point(const struct _lv_obj_t * obj, lv_point_t * p, bool recursive, bool inv);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform an area using the angle and zoom style properties of an object
|
|
||||||
* @param obj pointer to an object whose style properties should be used
|
|
||||||
* @param area an area to transform, the result will be written back here too
|
|
||||||
* @param recursive consider the transformation properties of the parents too
|
|
||||||
* @param inv do the inverse of the transformation (-angle and 1/zoom)
|
|
||||||
*/
|
|
||||||
void lv_obj_get_transformed_area(const struct _lv_obj_t * obj, lv_area_t * area, bool recursive, bool inv);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark an area of an object as invalid.
|
|
||||||
* The area will be truncated to the object's area and marked for redraw.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param area the area to redraw
|
|
||||||
*/
|
|
||||||
void lv_obj_invalidate_area(const struct _lv_obj_t * obj, const lv_area_t * area);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the object as invalid to redrawn its area
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_invalidate(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell whether an area of an object is visible (even partially) now or not
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param area the are to check. The visible part of the area will be written back here.
|
|
||||||
* @return true visible; false not visible (hidden, out of parent, on other screen, etc)
|
|
||||||
*/
|
|
||||||
bool lv_obj_area_is_visible(const struct _lv_obj_t * obj, lv_area_t * area);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell whether an object is visible (even partially) now or not
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return true: visible; false not visible (hidden, out of parent, on other screen, etc)
|
|
||||||
*/
|
|
||||||
bool lv_obj_is_visible(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of an extended clickable area
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param size extended clickable area in all 4 directions [px]
|
|
||||||
*/
|
|
||||||
void lv_obj_set_ext_click_area(struct _lv_obj_t * obj, lv_coord_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the an area where to object can be clicked.
|
|
||||||
* It's the object's normal area plus the extended click area.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param area store the result area here
|
|
||||||
*/
|
|
||||||
void lv_obj_get_click_area(const struct _lv_obj_t * obj, lv_area_t * area);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hit-test an object given a particular point in screen space.
|
|
||||||
* @param obj object to hit-test
|
|
||||||
* @param point screen-space point (absolute coordinate)
|
|
||||||
* @return true: if the object is considered under the point
|
|
||||||
*/
|
|
||||||
bool lv_obj_hit_test(struct _lv_obj_t * obj, const lv_point_t * point);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamp a width between min and max width. If the min/max width is in percentage value use the ref_width
|
|
||||||
* @param width width to clamp
|
|
||||||
* @param min_width the minimal width
|
|
||||||
* @param max_width the maximal width
|
|
||||||
* @param ref_width the reference width used when min/max width is in percentage
|
|
||||||
* @return the clamped width
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_clamp_width(lv_coord_t width, lv_coord_t min_width, lv_coord_t max_width, lv_coord_t ref_width);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamp a height between min and max height. If the min/max height is in percentage value use the ref_height
|
|
||||||
* @param height height to clamp
|
|
||||||
* @param min_height the minimal height
|
|
||||||
* @param max_height the maximal height
|
|
||||||
* @param ref_height the reference height used when min/max height is in percentage
|
|
||||||
* @return the clamped height
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_clamp_height(lv_coord_t height, lv_coord_t min_height, lv_coord_t max_height, lv_coord_t ref_height);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_POS_H*/
|
|
@ -1,800 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_scroll.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj_scroll.h"
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_indev.h"
|
|
||||||
#include "lv_disp.h"
|
|
||||||
#include "lv_indev_scroll.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
#define SCROLL_ANIM_TIME_MIN 200 /*ms*/
|
|
||||||
#define SCROLL_ANIM_TIME_MAX 400 /*ms*/
|
|
||||||
#define SCROLLBAR_MIN_SIZE (LV_DPX(10))
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void scroll_x_anim(void * obj, int32_t v);
|
|
||||||
static void scroll_y_anim(void * obj, int32_t v);
|
|
||||||
static void scroll_anim_ready_cb(lv_anim_t * a);
|
|
||||||
static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value,
|
|
||||||
lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Setter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
|
|
||||||
if(obj->spec_attr->scrollbar_mode == mode) return;
|
|
||||||
obj->spec_attr->scrollbar_mode = mode;
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir)
|
|
||||||
{
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
|
|
||||||
if(dir != obj->spec_attr->scroll_dir) {
|
|
||||||
obj->spec_attr->scroll_dir = dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align)
|
|
||||||
{
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
obj->spec_attr->scroll_snap_x = align;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align)
|
|
||||||
{
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
obj->spec_attr->scroll_snap_y = align;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Getter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->scrollbar_mode;
|
|
||||||
else return LV_SCROLLBAR_MODE_AUTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->scroll_dir;
|
|
||||||
else return LV_DIR_ALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->scroll_snap_x;
|
|
||||||
else return LV_SCROLL_SNAP_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr) return obj->spec_attr->scroll_snap_y;
|
|
||||||
else return LV_SCROLL_SNAP_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_x(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return -obj->spec_attr->scroll.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_y(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return -obj->spec_attr->scroll.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return -obj->spec_attr->scroll.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_coord_t child_res = LV_COORD_MIN;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
|
||||||
child_res = LV_MAX(child_res, child->coords.y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
if(child_res != LV_COORD_MIN) {
|
|
||||||
child_res -= (obj->coords.y2 - pad_bottom - border_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t self_h = lv_obj_get_self_height(obj);
|
|
||||||
self_h = self_h - (lv_obj_get_height(obj) - pad_top - pad_bottom - 2 * border_width);
|
|
||||||
self_h -= lv_obj_get_scroll_y(obj);
|
|
||||||
return LV_MAX(child_res, self_h);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
/*Normally can't scroll the object out on the left.
|
|
||||||
*So simply use the current scroll position as "left size"*/
|
|
||||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return -obj->spec_attr->scroll.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*With RTL base direction scrolling the left is normal so find the left most coordinate*/
|
|
||||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
lv_coord_t child_res = 0;
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
lv_coord_t x1 = LV_COORD_MAX;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
|
||||||
x1 = LV_MIN(x1, child->coords.x1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(x1 != LV_COORD_MAX) {
|
|
||||||
child_res = x1;
|
|
||||||
child_res = (obj->coords.x1 + pad_left + border_width) - child_res;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child_res = LV_COORD_MIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t self_w = lv_obj_get_self_width(obj);
|
|
||||||
self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left - 2 * border_width);
|
|
||||||
self_w += lv_obj_get_scroll_x(obj);
|
|
||||||
|
|
||||||
return LV_MAX(child_res, self_w);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
/*With RTL base dir can't scroll to the object out on the right.
|
|
||||||
*So simply use the current scroll position as "right size"*/
|
|
||||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) {
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return obj->spec_attr->scroll.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*With other base direction (LTR) scrolling to the right is normal so find the right most coordinate*/
|
|
||||||
lv_coord_t child_res = LV_COORD_MIN;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
|
||||||
child_res = LV_MAX(child_res, child->coords.x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
|
||||||
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
|
|
||||||
|
|
||||||
if(child_res != LV_COORD_MIN) {
|
|
||||||
child_res -= (obj->coords.x2 - pad_right - border_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t self_w;
|
|
||||||
self_w = lv_obj_get_self_width(obj);
|
|
||||||
self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left - 2 * border_width);
|
|
||||||
self_w -= lv_obj_get_scroll_x(obj);
|
|
||||||
return LV_MAX(child_res, self_w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end)
|
|
||||||
{
|
|
||||||
lv_anim_t * a;
|
|
||||||
a = lv_anim_get(obj, scroll_x_anim);
|
|
||||||
end->x = a ? -a->end_value : lv_obj_get_scroll_x(obj);
|
|
||||||
|
|
||||||
a = lv_anim_get(obj, scroll_y_anim);
|
|
||||||
end->y = a ? -a->end_value : lv_obj_get_scroll_y(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Other functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
void lv_obj_scroll_by_bounded(lv_obj_t * obj, lv_coord_t dx, lv_coord_t dy, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
if(dx == 0 && dy == 0) return;
|
|
||||||
|
|
||||||
/*We need to know the final sizes for bound check*/
|
|
||||||
lv_obj_update_layout(obj);
|
|
||||||
|
|
||||||
/*Don't let scroll more then naturally possible by the size of the content*/
|
|
||||||
lv_coord_t x_current = -lv_obj_get_scroll_x(obj);
|
|
||||||
lv_coord_t x_bounded = x_current + dx;
|
|
||||||
|
|
||||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
|
||||||
if(x_bounded > 0) x_bounded = 0;
|
|
||||||
if(x_bounded < 0) {
|
|
||||||
lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj);
|
|
||||||
if(scroll_max < 0) scroll_max = 0;
|
|
||||||
|
|
||||||
if(x_bounded < -scroll_max) x_bounded = -scroll_max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(x_bounded < 0) x_bounded = 0;
|
|
||||||
if(x_bounded > 0) {
|
|
||||||
lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj);
|
|
||||||
if(scroll_max < 0) scroll_max = 0;
|
|
||||||
|
|
||||||
if(x_bounded > scroll_max) x_bounded = scroll_max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Don't let scroll more then naturally possible by the size of the content*/
|
|
||||||
lv_coord_t y_current = -lv_obj_get_scroll_y(obj);
|
|
||||||
lv_coord_t y_bounded = y_current + dy;
|
|
||||||
|
|
||||||
if(y_bounded > 0) y_bounded = 0;
|
|
||||||
if(y_bounded < 0) {
|
|
||||||
lv_coord_t scroll_max = lv_obj_get_scroll_top(obj) + lv_obj_get_scroll_bottom(obj);
|
|
||||||
if(scroll_max < 0) scroll_max = 0;
|
|
||||||
if(y_bounded < -scroll_max) y_bounded = -scroll_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = x_bounded - x_current;
|
|
||||||
dy = y_bounded - y_current;
|
|
||||||
if(dx || dy) {
|
|
||||||
lv_obj_scroll_by(obj, dx, dy, anim_en);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t dx, lv_coord_t dy, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
if(dx == 0 && dy == 0) return;
|
|
||||||
if(anim_en == LV_ANIM_ON) {
|
|
||||||
lv_disp_t * d = lv_obj_get_disp(obj);
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, obj);
|
|
||||||
lv_anim_set_ready_cb(&a, scroll_anim_ready_cb);
|
|
||||||
|
|
||||||
if(dx) {
|
|
||||||
uint32_t t = lv_anim_speed_to_time((lv_disp_get_hor_res(d) * 2) >> 2, 0, dx);
|
|
||||||
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
|
|
||||||
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
|
|
||||||
lv_anim_set_time(&a, t);
|
|
||||||
lv_coord_t sx = lv_obj_get_scroll_x(obj);
|
|
||||||
lv_anim_set_values(&a, -sx, -sx + dx);
|
|
||||||
lv_anim_set_exec_cb(&a, scroll_x_anim);
|
|
||||||
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
|
|
||||||
|
|
||||||
lv_res_t res;
|
|
||||||
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, &a);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dy) {
|
|
||||||
uint32_t t = lv_anim_speed_to_time((lv_disp_get_ver_res(d) * 2) >> 2, 0, dy);
|
|
||||||
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
|
|
||||||
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
|
|
||||||
lv_anim_set_time(&a, t);
|
|
||||||
lv_coord_t sy = lv_obj_get_scroll_y(obj);
|
|
||||||
lv_anim_set_values(&a, -sy, -sy + dy);
|
|
||||||
lv_anim_set_exec_cb(&a, scroll_y_anim);
|
|
||||||
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
|
|
||||||
|
|
||||||
lv_res_t res;
|
|
||||||
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, &a);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Remove pending animations*/
|
|
||||||
lv_anim_del(obj, scroll_y_anim);
|
|
||||||
lv_anim_del(obj, scroll_x_anim);
|
|
||||||
|
|
||||||
lv_res_t res;
|
|
||||||
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, NULL);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
|
|
||||||
res = _lv_obj_scroll_by_raw(obj, dx, dy);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
|
|
||||||
res = lv_event_send(obj, LV_EVENT_SCROLL_END, NULL);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
lv_obj_scroll_to_x(obj, x, anim_en);
|
|
||||||
lv_obj_scroll_to_y(obj, y, anim_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
lv_anim_del(obj, scroll_x_anim);
|
|
||||||
|
|
||||||
lv_coord_t scroll_x = lv_obj_get_scroll_x(obj);
|
|
||||||
lv_coord_t diff = -x + scroll_x;
|
|
||||||
|
|
||||||
lv_obj_scroll_by_bounded(obj, diff, 0, anim_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
lv_anim_del(obj, scroll_y_anim);
|
|
||||||
|
|
||||||
lv_coord_t scroll_y = lv_obj_get_scroll_y(obj);
|
|
||||||
lv_coord_t diff = -y + scroll_y;
|
|
||||||
|
|
||||||
lv_obj_scroll_by_bounded(obj, 0, diff, anim_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
/*Be sure the screens layout is correct*/
|
|
||||||
lv_obj_update_layout(obj);
|
|
||||||
|
|
||||||
lv_point_t p = {0, 0};
|
|
||||||
scroll_area_into_view(&obj->coords, obj, &p, anim_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
/*Be sure the screens layout is correct*/
|
|
||||||
lv_obj_update_layout(obj);
|
|
||||||
|
|
||||||
lv_point_t p = {0, 0};
|
|
||||||
lv_obj_t * child = obj;
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(child);
|
|
||||||
while(parent) {
|
|
||||||
scroll_area_into_view(&obj->coords, child, &p, anim_en);
|
|
||||||
child = parent;
|
|
||||||
parent = lv_obj_get_parent(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_res_t _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
|
||||||
{
|
|
||||||
if(x == 0 && y == 0) return LV_RES_OK;
|
|
||||||
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
|
|
||||||
obj->spec_attr->scroll.x += x;
|
|
||||||
obj->spec_attr->scroll.y += y;
|
|
||||||
|
|
||||||
lv_obj_move_children_by(obj, x, y, true);
|
|
||||||
lv_res_t res = lv_event_send(obj, LV_EVENT_SCROLL, NULL);
|
|
||||||
if(res != LV_RES_OK) return res;
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool lv_obj_is_scrolling(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
|
||||||
while(indev) {
|
|
||||||
if(lv_indev_get_scroll_obj(indev) == obj) return true;
|
|
||||||
indev = lv_indev_get_next(indev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
lv_obj_update_layout(obj);
|
|
||||||
lv_point_t p;
|
|
||||||
lv_indev_scroll_get_snap_dist(obj, &p);
|
|
||||||
lv_obj_scroll_by(obj, p.x, p.y, anim_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * ver_area)
|
|
||||||
{
|
|
||||||
lv_area_set(hor_area, 0, 0, -1, -1);
|
|
||||||
lv_area_set(ver_area, 0, 0, -1, -1);
|
|
||||||
|
|
||||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) == false) return;
|
|
||||||
|
|
||||||
lv_dir_t sm = lv_obj_get_scrollbar_mode(obj);
|
|
||||||
if(sm == LV_SCROLLBAR_MODE_OFF) return;
|
|
||||||
|
|
||||||
/*If there is no indev scrolling this object but `mode==active` return*/
|
|
||||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
|
||||||
if(sm == LV_SCROLLBAR_MODE_ACTIVE) {
|
|
||||||
while(indev) {
|
|
||||||
if(lv_indev_get_scroll_obj(indev) == obj) break;
|
|
||||||
indev = lv_indev_get_next(indev);
|
|
||||||
}
|
|
||||||
if(indev == NULL) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(obj);
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
|
||||||
|
|
||||||
lv_dir_t dir = lv_obj_get_scroll_dir(obj);
|
|
||||||
|
|
||||||
bool ver_draw = false;
|
|
||||||
if((dir & LV_DIR_VER) &&
|
|
||||||
((sm == LV_SCROLLBAR_MODE_ON) ||
|
|
||||||
(sm == LV_SCROLLBAR_MODE_AUTO && (st > 0 || sb > 0)) ||
|
|
||||||
(sm == LV_SCROLLBAR_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_DIR_VER))) {
|
|
||||||
ver_draw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool hor_draw = false;
|
|
||||||
if((dir & LV_DIR_HOR) &&
|
|
||||||
((sm == LV_SCROLLBAR_MODE_ON) ||
|
|
||||||
(sm == LV_SCROLLBAR_MODE_AUTO && (sl > 0 || sr > 0)) ||
|
|
||||||
(sm == LV_SCROLLBAR_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_DIR_HOR))) {
|
|
||||||
hor_draw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hor_draw && !ver_draw) return;
|
|
||||||
|
|
||||||
bool rtl = lv_obj_get_style_base_dir(obj, LV_PART_SCROLLBAR) == LV_BASE_DIR_RTL ? true : false;
|
|
||||||
|
|
||||||
lv_coord_t top_space = lv_obj_get_style_pad_top(obj, LV_PART_SCROLLBAR);
|
|
||||||
lv_coord_t bottom_space = lv_obj_get_style_pad_bottom(obj, LV_PART_SCROLLBAR);
|
|
||||||
lv_coord_t left_space = lv_obj_get_style_pad_left(obj, LV_PART_SCROLLBAR);
|
|
||||||
lv_coord_t right_space = lv_obj_get_style_pad_right(obj, LV_PART_SCROLLBAR);
|
|
||||||
lv_coord_t tickness = lv_obj_get_style_width(obj, LV_PART_SCROLLBAR);
|
|
||||||
|
|
||||||
lv_coord_t obj_h = lv_obj_get_height(obj);
|
|
||||||
lv_coord_t obj_w = lv_obj_get_width(obj);
|
|
||||||
|
|
||||||
/*Space required for the vertical and horizontal scrollbars*/
|
|
||||||
lv_coord_t ver_reg_space = ver_draw ? tickness : 0;
|
|
||||||
lv_coord_t hor_req_space = hor_draw ? tickness : 0;
|
|
||||||
lv_coord_t rem;
|
|
||||||
|
|
||||||
if(lv_obj_get_style_bg_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN &&
|
|
||||||
lv_obj_get_style_border_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Draw vertical scrollbar if the mode is ON or can be scrolled in this direction*/
|
|
||||||
lv_coord_t content_h = obj_h + st + sb;
|
|
||||||
if(ver_draw && content_h) {
|
|
||||||
ver_area->y1 = obj->coords.y1;
|
|
||||||
ver_area->y2 = obj->coords.y2;
|
|
||||||
if(rtl) {
|
|
||||||
ver_area->x1 = obj->coords.x1 + left_space;
|
|
||||||
ver_area->x2 = ver_area->x1 + tickness - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ver_area->x2 = obj->coords.x2 - right_space;
|
|
||||||
ver_area->x1 = ver_area->x2 - tickness + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t sb_h = ((obj_h - top_space - bottom_space - hor_req_space) * obj_h) / content_h;
|
|
||||||
sb_h = LV_MAX(sb_h, SCROLLBAR_MIN_SIZE);
|
|
||||||
rem = (obj_h - top_space - bottom_space - hor_req_space) -
|
|
||||||
sb_h; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
|
||||||
lv_coord_t scroll_h = content_h - obj_h; /*The size of the content which can be really scrolled*/
|
|
||||||
if(scroll_h <= 0) {
|
|
||||||
ver_area->y1 = obj->coords.y1 + top_space;
|
|
||||||
ver_area->y2 = obj->coords.y2 - bottom_space - hor_req_space - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_coord_t sb_y = (rem * sb) / scroll_h;
|
|
||||||
sb_y = rem - sb_y;
|
|
||||||
|
|
||||||
ver_area->y1 = obj->coords.y1 + sb_y + top_space;
|
|
||||||
ver_area->y2 = ver_area->y1 + sb_h - 1;
|
|
||||||
if(ver_area->y1 < obj->coords.y1 + top_space) {
|
|
||||||
ver_area->y1 = obj->coords.y1 + top_space;
|
|
||||||
if(ver_area->y1 + SCROLLBAR_MIN_SIZE > ver_area->y2) {
|
|
||||||
ver_area->y2 = ver_area->y1 + SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ver_area->y2 > obj->coords.y2 - hor_req_space - bottom_space) {
|
|
||||||
ver_area->y2 = obj->coords.y2 - hor_req_space - bottom_space;
|
|
||||||
if(ver_area->y2 - SCROLLBAR_MIN_SIZE < ver_area->y1) {
|
|
||||||
ver_area->y1 = ver_area->y2 - SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
|
|
||||||
lv_coord_t content_w = obj_w + sl + sr;
|
|
||||||
if(hor_draw && content_w) {
|
|
||||||
hor_area->y2 = obj->coords.y2 - bottom_space;
|
|
||||||
hor_area->y1 = hor_area->y2 - tickness + 1;
|
|
||||||
hor_area->x1 = obj->coords.x1;
|
|
||||||
hor_area->x2 = obj->coords.x2;
|
|
||||||
|
|
||||||
lv_coord_t sb_w = ((obj_w - left_space - right_space - ver_reg_space) * obj_w) / content_w;
|
|
||||||
sb_w = LV_MAX(sb_w, SCROLLBAR_MIN_SIZE);
|
|
||||||
rem = (obj_w - left_space - right_space - ver_reg_space) -
|
|
||||||
sb_w; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
|
||||||
lv_coord_t scroll_w = content_w - obj_w; /*The size of the content which can be really scrolled*/
|
|
||||||
if(scroll_w <= 0) {
|
|
||||||
if(rtl) {
|
|
||||||
hor_area->x1 = obj->coords.x1 + left_space + ver_reg_space - 1;
|
|
||||||
hor_area->x2 = obj->coords.x2 - right_space;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hor_area->x1 = obj->coords.x1 + left_space;
|
|
||||||
hor_area->x2 = obj->coords.x2 - right_space - ver_reg_space - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_coord_t sb_x = (rem * sr) / scroll_w;
|
|
||||||
sb_x = rem - sb_x;
|
|
||||||
|
|
||||||
if(rtl) {
|
|
||||||
hor_area->x1 = obj->coords.x1 + sb_x + left_space + ver_reg_space;
|
|
||||||
hor_area->x2 = hor_area->x1 + sb_w - 1;
|
|
||||||
if(hor_area->x1 < obj->coords.x1 + left_space + ver_reg_space) {
|
|
||||||
hor_area->x1 = obj->coords.x1 + left_space + ver_reg_space;
|
|
||||||
if(hor_area->x1 + SCROLLBAR_MIN_SIZE > hor_area->x2) {
|
|
||||||
hor_area->x2 = hor_area->x1 + SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hor_area->x2 > obj->coords.x2 - right_space) {
|
|
||||||
hor_area->x2 = obj->coords.x2 - right_space;
|
|
||||||
if(hor_area->x2 - SCROLLBAR_MIN_SIZE < hor_area->x1) {
|
|
||||||
hor_area->x1 = hor_area->x2 - SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hor_area->x1 = obj->coords.x1 + sb_x + left_space;
|
|
||||||
hor_area->x2 = hor_area->x1 + sb_w - 1;
|
|
||||||
if(hor_area->x1 < obj->coords.x1 + left_space) {
|
|
||||||
hor_area->x1 = obj->coords.x1 + left_space;
|
|
||||||
if(hor_area->x1 + SCROLLBAR_MIN_SIZE > hor_area->x2) {
|
|
||||||
hor_area->x2 = hor_area->x1 + SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hor_area->x2 > obj->coords.x2 - ver_reg_space - right_space) {
|
|
||||||
hor_area->x2 = obj->coords.x2 - ver_reg_space - right_space;
|
|
||||||
if(hor_area->x2 - SCROLLBAR_MIN_SIZE < hor_area->x1) {
|
|
||||||
hor_area->x1 = hor_area->x2 - SCROLLBAR_MIN_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_scrollbar_invalidate(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_area_t hor_area;
|
|
||||||
lv_area_t ver_area;
|
|
||||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
|
||||||
|
|
||||||
if(lv_area_get_size(&hor_area) <= 0 && lv_area_get_size(&ver_area) <= 0) return;
|
|
||||||
|
|
||||||
if(lv_area_get_size(&hor_area) > 0) lv_obj_invalidate_area(obj, &hor_area);
|
|
||||||
if(lv_area_get_size(&ver_area) > 0) lv_obj_invalidate_area(obj, &ver_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
/*Be sure the bottom side is not remains scrolled in*/
|
|
||||||
/*With snapping the content can't be scrolled in*/
|
|
||||||
if(lv_obj_get_scroll_snap_y(obj) == LV_SCROLL_SNAP_NONE) {
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(obj);
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
|
|
||||||
if(sb < 0 && st > 0) {
|
|
||||||
sb = LV_MIN(st, -sb);
|
|
||||||
lv_obj_scroll_by(obj, 0, sb, anim_en);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lv_obj_get_scroll_snap_x(obj) == LV_SCROLL_SNAP_NONE) {
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
|
||||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
|
||||||
/*Be sure the left side is not remains scrolled in*/
|
|
||||||
if(sr < 0 && sl > 0) {
|
|
||||||
sr = LV_MIN(sl, -sr);
|
|
||||||
lv_obj_scroll_by(obj, sr, 0, anim_en);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Be sure the right side is not remains scrolled in*/
|
|
||||||
if(sl < 0 && sr > 0) {
|
|
||||||
sr = LV_MIN(sr, -sl);
|
|
||||||
lv_obj_scroll_by(obj, sl, 0, anim_en);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
|
|
||||||
static void scroll_x_anim(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
_lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_x(obj), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scroll_y_anim(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
_lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_y(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scroll_anim_ready_cb(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
lv_event_send(a->var, LV_EVENT_SCROLL_END, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value,
|
|
||||||
lv_anim_enable_t anim_en)
|
|
||||||
{
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(child);
|
|
||||||
if(!lv_obj_has_flag(parent, LV_OBJ_FLAG_SCROLLABLE)) return;
|
|
||||||
|
|
||||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(parent);
|
|
||||||
lv_coord_t snap_goal = 0;
|
|
||||||
lv_coord_t act = 0;
|
|
||||||
const lv_area_t * area_tmp;
|
|
||||||
|
|
||||||
lv_coord_t y_scroll = 0;
|
|
||||||
lv_scroll_snap_t snap_y = lv_obj_get_scroll_snap_y(parent);
|
|
||||||
if(snap_y != LV_SCROLL_SNAP_NONE) area_tmp = &child->coords;
|
|
||||||
else area_tmp = area;
|
|
||||||
|
|
||||||
lv_coord_t border_width = lv_obj_get_style_border_width(parent, LV_PART_MAIN);
|
|
||||||
lv_coord_t ptop = lv_obj_get_style_pad_top(parent, LV_PART_MAIN) + border_width;
|
|
||||||
lv_coord_t pbottom = lv_obj_get_style_pad_bottom(parent, LV_PART_MAIN) + border_width;
|
|
||||||
lv_coord_t top_diff = parent->coords.y1 + ptop - area_tmp->y1 - scroll_value->y;
|
|
||||||
lv_coord_t bottom_diff = -(parent->coords.y2 - pbottom - area_tmp->y2 - scroll_value->y);
|
|
||||||
lv_coord_t parent_h = lv_obj_get_height(parent) - ptop - pbottom;
|
|
||||||
if((top_diff >= 0 && bottom_diff >= 0)) y_scroll = 0;
|
|
||||||
else if(top_diff > 0) {
|
|
||||||
y_scroll = top_diff;
|
|
||||||
/*Do not let scrolling in*/
|
|
||||||
lv_coord_t st = lv_obj_get_scroll_top(parent);
|
|
||||||
if(st - y_scroll < 0) y_scroll = 0;
|
|
||||||
}
|
|
||||||
else if(bottom_diff > 0) {
|
|
||||||
y_scroll = -bottom_diff;
|
|
||||||
/*Do not let scrolling in*/
|
|
||||||
lv_coord_t sb = lv_obj_get_scroll_bottom(parent);
|
|
||||||
if(sb + y_scroll < 0) y_scroll = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(snap_y) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
snap_goal = parent->coords.y1 + ptop;
|
|
||||||
act = area_tmp->y1 + y_scroll;
|
|
||||||
y_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
snap_goal = parent->coords.y2 - pbottom;
|
|
||||||
act = area_tmp->y2 + y_scroll;
|
|
||||||
y_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
snap_goal = parent->coords.y1 + ptop + parent_h / 2;
|
|
||||||
act = lv_area_get_height(area_tmp) / 2 + area_tmp->y1 + y_scroll;
|
|
||||||
y_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t x_scroll = 0;
|
|
||||||
lv_scroll_snap_t snap_x = lv_obj_get_scroll_snap_x(parent);
|
|
||||||
if(snap_x != LV_SCROLL_SNAP_NONE) area_tmp = &child->coords;
|
|
||||||
else area_tmp = area;
|
|
||||||
|
|
||||||
lv_coord_t pleft = lv_obj_get_style_pad_left(parent, LV_PART_MAIN) + border_width;
|
|
||||||
lv_coord_t pright = lv_obj_get_style_pad_right(parent, LV_PART_MAIN) + border_width;
|
|
||||||
lv_coord_t left_diff = parent->coords.x1 + pleft - area_tmp->x1 - scroll_value->x;
|
|
||||||
lv_coord_t right_diff = -(parent->coords.x2 - pright - area_tmp->x2 - scroll_value->x);
|
|
||||||
if((left_diff >= 0 && right_diff >= 0)) x_scroll = 0;
|
|
||||||
else if(left_diff > 0) {
|
|
||||||
x_scroll = left_diff;
|
|
||||||
/*Do not let scrolling in*/
|
|
||||||
lv_coord_t sl = lv_obj_get_scroll_left(parent);
|
|
||||||
if(sl - x_scroll < 0) x_scroll = 0;
|
|
||||||
}
|
|
||||||
else if(right_diff > 0) {
|
|
||||||
x_scroll = -right_diff;
|
|
||||||
/*Do not let scrolling in*/
|
|
||||||
lv_coord_t sr = lv_obj_get_scroll_right(parent);
|
|
||||||
if(sr + x_scroll < 0) x_scroll = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_coord_t parent_w = lv_obj_get_width(parent) - pleft - pright;
|
|
||||||
switch(snap_x) {
|
|
||||||
case LV_SCROLL_SNAP_START:
|
|
||||||
snap_goal = parent->coords.x1 + pleft;
|
|
||||||
act = area_tmp->x1 + x_scroll;
|
|
||||||
x_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_END:
|
|
||||||
snap_goal = parent->coords.x2 - pright;
|
|
||||||
act = area_tmp->x2 + x_scroll;
|
|
||||||
x_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
case LV_SCROLL_SNAP_CENTER:
|
|
||||||
snap_goal = parent->coords.x1 + pleft + parent_w / 2;
|
|
||||||
act = lv_area_get_width(area_tmp) / 2 + area_tmp->x1 + x_scroll;
|
|
||||||
x_scroll += snap_goal - act;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Remove any pending scroll animations.*/
|
|
||||||
bool y_del = lv_anim_del(parent, scroll_y_anim);
|
|
||||||
bool x_del = lv_anim_del(parent, scroll_x_anim);
|
|
||||||
if(y_del || x_del) {
|
|
||||||
lv_res_t res;
|
|
||||||
res = lv_event_send(parent, LV_EVENT_SCROLL_END, NULL);
|
|
||||||
if(res != LV_RES_OK) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((scroll_dir & LV_DIR_LEFT) == 0 && x_scroll < 0) x_scroll = 0;
|
|
||||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && x_scroll > 0) x_scroll = 0;
|
|
||||||
if((scroll_dir & LV_DIR_TOP) == 0 && y_scroll < 0) y_scroll = 0;
|
|
||||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && y_scroll > 0) y_scroll = 0;
|
|
||||||
|
|
||||||
scroll_value->x += anim_en == LV_ANIM_OFF ? 0 : x_scroll;
|
|
||||||
scroll_value->y += anim_en == LV_ANIM_OFF ? 0 : y_scroll;
|
|
||||||
lv_obj_scroll_by(parent, x_scroll, y_scroll, anim_en);
|
|
||||||
}
|
|
@ -1,307 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_scroll.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_SCROLL_H
|
|
||||||
#define LV_OBJ_SCROLL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../misc/lv_area.h"
|
|
||||||
#include "../misc/lv_anim.h"
|
|
||||||
#include "../misc/lv_types.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*Can't include lv_obj.h because it includes this header file*/
|
|
||||||
struct _lv_obj_t;
|
|
||||||
|
|
||||||
/** Scrollbar modes: shows when should the scrollbars be visible*/
|
|
||||||
enum {
|
|
||||||
LV_SCROLLBAR_MODE_OFF, /**< Never show scrollbars*/
|
|
||||||
LV_SCROLLBAR_MODE_ON, /**< Always show scrollbars*/
|
|
||||||
LV_SCROLLBAR_MODE_ACTIVE, /**< Show scroll bars when object is being scrolled*/
|
|
||||||
LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/
|
|
||||||
};
|
|
||||||
typedef uint8_t lv_scrollbar_mode_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Scroll span align options. Tells where to align the snappable children when scroll stops.*/
|
|
||||||
enum {
|
|
||||||
LV_SCROLL_SNAP_NONE, /**< Do not align, leave where it is*/
|
|
||||||
LV_SCROLL_SNAP_START, /**< Align to the left/top*/
|
|
||||||
LV_SCROLL_SNAP_END, /**< Align to the right/bottom*/
|
|
||||||
LV_SCROLL_SNAP_CENTER /**< Align to the center*/
|
|
||||||
};
|
|
||||||
typedef uint8_t lv_scroll_snap_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Setter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set how the scrollbars should behave.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param mode LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE
|
|
||||||
*/
|
|
||||||
void lv_obj_set_scrollbar_mode(struct _lv_obj_t * obj, lv_scrollbar_mode_t mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the object in which directions can be scrolled
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set where to snap the children when scrolling ends horizontally
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param align the snap align to set from `lv_scroll_snap_t`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_scroll_snap_x(struct _lv_obj_t * obj, lv_scroll_snap_t align);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set where to snap the children when scrolling ends vertically
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param align the snap align to set from `lv_scroll_snap_t`
|
|
||||||
*/
|
|
||||||
void lv_obj_set_scroll_snap_y(struct _lv_obj_t * obj, lv_scroll_snap_t align);
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Getter functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current scroll mode (when to hide the scrollbars)
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the current scroll mode from `lv_scrollbar_mode_t`
|
|
||||||
*/
|
|
||||||
lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the object in which directions can be scrolled
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t`
|
|
||||||
*/
|
|
||||||
lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get where to snap the children when scrolling ends horizontally
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the current snap align from `lv_scroll_snap_t`
|
|
||||||
*/
|
|
||||||
lv_scroll_snap_t lv_obj_get_scroll_snap_x(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get where to snap the children when scrolling ends vertically
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the current snap align from `lv_scroll_snap_t`
|
|
||||||
*/
|
|
||||||
lv_scroll_snap_t lv_obj_get_scroll_snap_y(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current X scroll position.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the current scroll position from the left edge.
|
|
||||||
* If the object is not scrolled return 0
|
|
||||||
* If scrolled return > 0
|
|
||||||
* If scrolled in (elastic scroll) return < 0
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_x(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current Y scroll position.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the current scroll position from the top edge.
|
|
||||||
* If the object is not scrolled return 0
|
|
||||||
* If scrolled return > 0
|
|
||||||
* If scrolled inside return < 0
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_y(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the height of the area above the object.
|
|
||||||
* That is the number of pixels the object can be scrolled down.
|
|
||||||
* Normally positive but can be negative when scrolled inside.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the scrollable area above the object in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_top(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the height of the area below the object.
|
|
||||||
* That is the number of pixels the object can be scrolled down.
|
|
||||||
* Normally positive but can be negative when scrolled inside.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the scrollable area below the object in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_bottom(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the width of the area on the left the object.
|
|
||||||
* That is the number of pixels the object can be scrolled down.
|
|
||||||
* Normally positive but can be negative when scrolled inside.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the scrollable area on the left the object in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_left(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the width of the area on the right the object.
|
|
||||||
* That is the number of pixels the object can be scrolled down.
|
|
||||||
* Normally positive but can be negative when scrolled inside.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the scrollable area on the right the object in pixels
|
|
||||||
*/
|
|
||||||
lv_coord_t lv_obj_get_scroll_right(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the X and Y coordinates where the scrolling will end for this object if a scrolling animation is in progress.
|
|
||||||
* If no scrolling animation, give the current `x` or `y` scroll position.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param end pointer to store the result
|
|
||||||
*/
|
|
||||||
void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end);
|
|
||||||
|
|
||||||
/*=====================
|
|
||||||
* Other functions
|
|
||||||
*====================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll by a given amount of pixels
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param dx pixels to scroll horizontally
|
|
||||||
* @param dy pixels to scroll vertically
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
* @note > 0 value means scroll right/bottom (show the more content on the right/bottom)
|
|
||||||
* @note e.g. dy = -20 means scroll down 20 px
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_by(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll by a given amount of pixels.
|
|
||||||
* `dx` and `dy` will be limited internally to allow scrolling only on the content area.
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param dx pixels to scroll horizontally
|
|
||||||
* @param dy pixels to scroll vertically
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
* @note e.g. dy = -20 means scroll down 20 px
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_by_bounded(struct _lv_obj_t * obj, lv_coord_t dx, lv_coord_t dy, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll to a given coordinate on an object.
|
|
||||||
* `x` and `y` will be limited internally to allow scrolling only on the content area.
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param x pixels to scroll horizontally
|
|
||||||
* @param y pixels to scroll vertically
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll to a given X coordinate on an object.
|
|
||||||
* `x` will be limited internally to allow scrolling only on the content area.
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param x pixels to scroll horizontally
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_to_x(struct _lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll to a given Y coordinate on an object
|
|
||||||
* `y` will be limited internally to allow scrolling only on the content area.
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param y pixels to scroll vertically
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_to_y(struct _lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll to an object until it becomes visible on its parent
|
|
||||||
* @param obj pointer to an object to scroll into view
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_to_view(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scroll to an object until it becomes visible on its parent.
|
|
||||||
* Do the same on the parent's parent, and so on.
|
|
||||||
* Therefore the object will be scrolled into view even it has nested scrollable parents
|
|
||||||
* @param obj pointer to an object to scroll into view
|
|
||||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
|
||||||
*/
|
|
||||||
void lv_obj_scroll_to_view_recursive(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Low level function to scroll by given x and y coordinates.
|
|
||||||
* `LV_EVENT_SCROLL` is sent.
|
|
||||||
* @param obj pointer to an object to scroll
|
|
||||||
* @param x pixels to scroll horizontally
|
|
||||||
* @param y pixels to scroll vertically
|
|
||||||
* @return `LV_RES_INV`: to object was deleted in `LV_EVENT_SCROLL`;
|
|
||||||
* `LV_RES_OK`: if the object is still valid
|
|
||||||
*/
|
|
||||||
lv_res_t _lv_obj_scroll_by_raw(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell whether an object is being scrolled or not at this moment
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return true: `obj` is being scrolled
|
|
||||||
*/
|
|
||||||
bool lv_obj_is_scrolling(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the children of `obj` and scroll `obj` to fulfill the scroll_snap settings
|
|
||||||
* @param obj an object whose children needs to checked and snapped
|
|
||||||
* @param anim_en LV_ANIM_ON/OFF
|
|
||||||
*/
|
|
||||||
void lv_obj_update_snap(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the area of the scrollbars
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param hor pointer to store the area of the horizontal scrollbar
|
|
||||||
* @param ver pointer to store the area of the vertical scrollbar
|
|
||||||
*/
|
|
||||||
void lv_obj_get_scrollbar_area(struct _lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the area of the scrollbars
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_scrollbar_invalidate(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checked if the content is scrolled "in" and adjusts it to a normal position.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param anim_en LV_ANIM_ON/OFF
|
|
||||||
*/
|
|
||||||
void lv_obj_readjust_scroll(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_SCROLL_H*/
|
|
@ -1,861 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_style.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_disp.h"
|
|
||||||
#include "../misc/lv_gc.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lv_obj_t * obj;
|
|
||||||
lv_style_prop_t prop;
|
|
||||||
lv_style_selector_t selector;
|
|
||||||
lv_style_value_t start_value;
|
|
||||||
lv_style_value_t end_value;
|
|
||||||
} trans_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CACHE_ZERO = 0,
|
|
||||||
CACHE_TRUE = 1,
|
|
||||||
CACHE_UNSET = 2,
|
|
||||||
CACHE_255 = 3,
|
|
||||||
CACHE_NEED_CHECK = 4,
|
|
||||||
} cache_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector);
|
|
||||||
static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part);
|
|
||||||
static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v);
|
|
||||||
static void report_style_change_core(void * style, lv_obj_t * obj);
|
|
||||||
static void refresh_children_style(lv_obj_t * obj);
|
|
||||||
static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit);
|
|
||||||
static void trans_anim_cb(void * _tr, int32_t v);
|
|
||||||
static void trans_anim_start_cb(lv_anim_t * a);
|
|
||||||
static void trans_anim_ready_cb(lv_anim_t * a);
|
|
||||||
static lv_layer_type_t calculate_layer_type(lv_obj_t * obj);
|
|
||||||
static void fade_anim_cb(void * obj, int32_t v);
|
|
||||||
static void fade_in_anim_ready(lv_anim_t * a);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static bool style_refr = true;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void _lv_obj_style_init(void)
|
|
||||||
{
|
|
||||||
_lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(trans_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_add_style(lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
trans_del(obj, selector, LV_STYLE_PROP_ANY, NULL);
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
/*Go after the transition and local styles*/
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans) continue;
|
|
||||||
if(obj->styles[i].is_local) continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Now `i` is at the first normal style. Insert the new style before this*/
|
|
||||||
|
|
||||||
/*Allocate space for the new style and shift the rest of the style to the end*/
|
|
||||||
obj->style_cnt++;
|
|
||||||
obj->styles = lv_mem_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t));
|
|
||||||
|
|
||||||
uint32_t j;
|
|
||||||
for(j = obj->style_cnt - 1; j > i ; j--) {
|
|
||||||
obj->styles[j] = obj->styles[j - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_memset_00(&obj->styles[i], sizeof(_lv_obj_style_t));
|
|
||||||
obj->styles[i].style = style;
|
|
||||||
obj->styles[i].selector = selector;
|
|
||||||
|
|
||||||
lv_obj_refresh_style(obj, selector, LV_STYLE_PROP_ANY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_remove_style(lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_state_t state = lv_obj_style_get_selector_state(selector);
|
|
||||||
lv_part_t part = lv_obj_style_get_selector_part(selector);
|
|
||||||
lv_style_prop_t prop = LV_STYLE_PROP_ANY;
|
|
||||||
if(style && style->prop_cnt == 0) prop = LV_STYLE_PROP_INV;
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
bool deleted = false;
|
|
||||||
while(i < obj->style_cnt) {
|
|
||||||
lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector);
|
|
||||||
lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector);
|
|
||||||
if((state != LV_STATE_ANY && state_act != state) ||
|
|
||||||
(part != LV_PART_ANY && part_act != part) ||
|
|
||||||
(style != NULL && style != obj->styles[i].style)) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->styles[i].is_trans) {
|
|
||||||
trans_del(obj, part, LV_STYLE_PROP_ANY, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->styles[i].is_local || obj->styles[i].is_trans) {
|
|
||||||
lv_style_reset(obj->styles[i].style);
|
|
||||||
lv_mem_free(obj->styles[i].style);
|
|
||||||
obj->styles[i].style = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Shift the styles after `i` by one*/
|
|
||||||
uint32_t j;
|
|
||||||
for(j = i; j < (uint32_t)obj->style_cnt - 1 ; j++) {
|
|
||||||
obj->styles[j] = obj->styles[j + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->style_cnt--;
|
|
||||||
obj->styles = lv_mem_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t));
|
|
||||||
|
|
||||||
deleted = true;
|
|
||||||
/*The style from the current `i` index is removed, so `i` points to the next style.
|
|
||||||
*Therefore it doesn't needs to be incremented*/
|
|
||||||
}
|
|
||||||
if(deleted && prop != LV_STYLE_PROP_INV) {
|
|
||||||
lv_obj_refresh_style(obj, part, prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_report_style_change(lv_style_t * style)
|
|
||||||
{
|
|
||||||
if(!style_refr) return;
|
|
||||||
lv_disp_t * d = lv_disp_get_next(NULL);
|
|
||||||
|
|
||||||
while(d) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < d->screen_cnt; i++) {
|
|
||||||
report_style_change_core(style, d->screens[i]);
|
|
||||||
}
|
|
||||||
d = lv_disp_get_next(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(!style_refr) return;
|
|
||||||
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
lv_part_t part = lv_obj_style_get_selector_part(selector);
|
|
||||||
|
|
||||||
bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYOUT_REFR);
|
|
||||||
bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_EXT_DRAW);
|
|
||||||
bool is_inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
|
||||||
bool is_layer_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYER_REFR);
|
|
||||||
|
|
||||||
if(is_layout_refr) {
|
|
||||||
if(part == LV_PART_ANY ||
|
|
||||||
part == LV_PART_MAIN ||
|
|
||||||
lv_obj_get_style_height(obj, 0) == LV_SIZE_CONTENT ||
|
|
||||||
lv_obj_get_style_width(obj, 0) == LV_SIZE_CONTENT) {
|
|
||||||
lv_event_send(obj, LV_EVENT_STYLE_CHANGED, NULL);
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((part == LV_PART_ANY || part == LV_PART_MAIN) && (prop == LV_STYLE_PROP_ANY || is_layout_refr)) {
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
|
||||||
if(parent) lv_obj_mark_layout_as_dirty(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Cache the layer type*/
|
|
||||||
if((part == LV_PART_ANY || part == LV_PART_MAIN) && is_layer_refr) {
|
|
||||||
lv_layer_type_t layer_type = calculate_layer_type(obj);
|
|
||||||
if(obj->spec_attr) obj->spec_attr->layer_type = layer_type;
|
|
||||||
else if(layer_type != LV_LAYER_TYPE_NONE) {
|
|
||||||
lv_obj_allocate_spec_attr(obj);
|
|
||||||
obj->spec_attr->layer_type = layer_type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(prop == LV_STYLE_PROP_ANY || is_ext_draw) {
|
|
||||||
lv_obj_refresh_ext_draw_size(obj);
|
|
||||||
}
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
if(prop == LV_STYLE_PROP_ANY || (is_inheritable && (is_ext_draw || is_layout_refr))) {
|
|
||||||
if(part != LV_PART_SCROLLBAR) {
|
|
||||||
refresh_children_style(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_enable_style_refresh(bool en)
|
|
||||||
{
|
|
||||||
style_refr = en;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
|
|
||||||
{
|
|
||||||
lv_style_value_t value_act;
|
|
||||||
bool inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
|
||||||
lv_style_res_t found = LV_STYLE_RES_NOT_FOUND;
|
|
||||||
while(obj) {
|
|
||||||
found = get_prop_core(obj, part, prop, &value_act);
|
|
||||||
if(found == LV_STYLE_RES_FOUND) break;
|
|
||||||
if(!inheritable) break;
|
|
||||||
|
|
||||||
/*If not found, check the `MAIN` style first*/
|
|
||||||
if(found != LV_STYLE_RES_INHERIT && part != LV_PART_MAIN) {
|
|
||||||
part = LV_PART_MAIN;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Check the parent too.*/
|
|
||||||
obj = lv_obj_get_parent(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(found != LV_STYLE_RES_FOUND) {
|
|
||||||
if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) {
|
|
||||||
const lv_obj_class_t * cls = obj->class_p;
|
|
||||||
while(cls) {
|
|
||||||
if(prop == LV_STYLE_WIDTH) {
|
|
||||||
if(cls->width_def != 0) break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(cls->height_def != 0) break;
|
|
||||||
}
|
|
||||||
cls = cls->base_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cls) {
|
|
||||||
value_act.num = prop == LV_STYLE_WIDTH ? cls->width_def : cls->height_def;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value_act.num = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value_act = lv_style_prop_get_default(prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value_act;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
|
|
||||||
lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_t * style = get_local_style(obj, selector);
|
|
||||||
lv_style_set_prop(style, prop, value);
|
|
||||||
lv_obj_refresh_style(obj, selector, prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_local_style_prop_meta(lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta,
|
|
||||||
lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_t * style = get_local_style(obj, selector);
|
|
||||||
lv_style_set_prop_meta(style, prop, meta);
|
|
||||||
lv_obj_refresh_style(obj, selector, prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
|
||||||
lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_local &&
|
|
||||||
obj->styles[i].selector == selector) {
|
|
||||||
return lv_style_get_prop(obj->styles[i].style, prop, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return LV_STYLE_RES_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
/*Find the style*/
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_local &&
|
|
||||||
obj->styles[i].selector == selector) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*The style is not found*/
|
|
||||||
if(i == obj->style_cnt) return false;
|
|
||||||
|
|
||||||
return lv_style_remove_prop(obj->styles[i].style, prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, lv_state_t new_state,
|
|
||||||
const _lv_obj_style_transition_dsc_t * tr_dsc)
|
|
||||||
{
|
|
||||||
trans_t * tr;
|
|
||||||
|
|
||||||
/*Get the previous and current values*/
|
|
||||||
obj->skip_trans = 1;
|
|
||||||
obj->state = prev_state;
|
|
||||||
lv_style_value_t v1 = lv_obj_get_style_prop(obj, part, tr_dsc->prop);
|
|
||||||
obj->state = new_state;
|
|
||||||
lv_style_value_t v2 = lv_obj_get_style_prop(obj, part, tr_dsc->prop);
|
|
||||||
obj->skip_trans = 0;
|
|
||||||
|
|
||||||
if(v1.ptr == v2.ptr && v1.num == v2.num && v1.color.full == v2.color.full) return;
|
|
||||||
obj->state = prev_state;
|
|
||||||
v1 = lv_obj_get_style_prop(obj, part, tr_dsc->prop);
|
|
||||||
obj->state = new_state;
|
|
||||||
|
|
||||||
_lv_obj_style_t * style_trans = get_trans_style(obj, part);
|
|
||||||
lv_style_set_prop(style_trans->style, tr_dsc->prop, v1); /*Be sure `trans_style` has a valid value*/
|
|
||||||
|
|
||||||
if(tr_dsc->prop == LV_STYLE_RADIUS) {
|
|
||||||
if(v1.num == LV_RADIUS_CIRCLE || v2.num == LV_RADIUS_CIRCLE) {
|
|
||||||
lv_coord_t whalf = lv_obj_get_width(obj) / 2;
|
|
||||||
lv_coord_t hhalf = lv_obj_get_height(obj) / 2;
|
|
||||||
if(v1.num == LV_RADIUS_CIRCLE) v1.num = LV_MIN(whalf + 1, hhalf + 1);
|
|
||||||
if(v2.num == LV_RADIUS_CIRCLE) v2.num = LV_MIN(whalf + 1, hhalf + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tr = _lv_ll_ins_head(&LV_GC_ROOT(_lv_obj_style_trans_ll));
|
|
||||||
LV_ASSERT_MALLOC(tr);
|
|
||||||
if(tr == NULL) return;
|
|
||||||
tr->start_value = v1;
|
|
||||||
tr->end_value = v2;
|
|
||||||
tr->obj = obj;
|
|
||||||
tr->prop = tr_dsc->prop;
|
|
||||||
tr->selector = part;
|
|
||||||
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, tr);
|
|
||||||
lv_anim_set_exec_cb(&a, trans_anim_cb);
|
|
||||||
lv_anim_set_start_cb(&a, trans_anim_start_cb);
|
|
||||||
lv_anim_set_ready_cb(&a, trans_anim_ready_cb);
|
|
||||||
lv_anim_set_values(&a, 0x00, 0xFF);
|
|
||||||
lv_anim_set_time(&a, tr_dsc->time);
|
|
||||||
lv_anim_set_delay(&a, tr_dsc->delay);
|
|
||||||
lv_anim_set_path_cb(&a, tr_dsc->path_cb);
|
|
||||||
lv_anim_set_early_apply(&a, false);
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
a.user_data = tr_dsc->user_data;
|
|
||||||
#endif
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lv_style_value_t _lv_obj_style_apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v)
|
|
||||||
{
|
|
||||||
if(obj == NULL) return v;
|
|
||||||
const lv_color_filter_dsc_t * f = lv_obj_get_style_color_filter_dsc(obj, part);
|
|
||||||
if(f && f->filter_cb) {
|
|
||||||
lv_opa_t f_opa = lv_obj_get_style_color_filter_opa(obj, part);
|
|
||||||
if(f_opa != 0) v.color = f->filter_cb(f, v.color, f_opa);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2)
|
|
||||||
{
|
|
||||||
_lv_style_state_cmp_t res = _LV_STYLE_STATE_CMP_SAME;
|
|
||||||
|
|
||||||
/*Are there any new styles for the new state?*/
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans) continue;
|
|
||||||
|
|
||||||
lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector);
|
|
||||||
/*The style is valid for a state but not the other*/
|
|
||||||
bool valid1 = state_act & (~state1) ? false : true;
|
|
||||||
bool valid2 = state_act & (~state2) ? false : true;
|
|
||||||
if(valid1 != valid2) {
|
|
||||||
lv_style_t * style = obj->styles[i].style;
|
|
||||||
lv_style_value_t v;
|
|
||||||
/*If there is layout difference on the main part, return immediately. There is no more serious difference*/
|
|
||||||
bool layout_diff = false;
|
|
||||||
if(lv_style_get_prop(style, LV_STYLE_PAD_TOP, &v))layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_PAD_BOTTOM, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_PAD_LEFT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_PAD_RIGHT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_PAD_COLUMN, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_PAD_ROW, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_LAYOUT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSLATE_X, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSLATE_Y, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_WIDTH, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_HEIGHT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_MIN_WIDTH, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_MAX_WIDTH, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_MIN_HEIGHT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_MAX_HEIGHT, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_BORDER_WIDTH, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ANGLE, &v)) layout_diff = true;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ZOOM, &v)) layout_diff = true;
|
|
||||||
|
|
||||||
if(layout_diff) {
|
|
||||||
return _LV_STYLE_STATE_CMP_DIFF_LAYOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Check for draw pad changes*/
|
|
||||||
if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_HEIGHT, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ANGLE, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ZOOM, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_OPA, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_PAD, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_SHADOW_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OPA, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFS_X, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFS_Y, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_SHADOW_SPREAD, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(lv_style_get_prop(style, LV_STYLE_LINE_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD;
|
|
||||||
else if(res == _LV_STYLE_STATE_CMP_SAME) res = _LV_STYLE_STATE_CMP_DIFF_REDRAW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay)
|
|
||||||
{
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, obj);
|
|
||||||
lv_anim_set_values(&a, 0, LV_OPA_COVER);
|
|
||||||
lv_anim_set_exec_cb(&a, fade_anim_cb);
|
|
||||||
lv_anim_set_ready_cb(&a, fade_in_anim_ready);
|
|
||||||
lv_anim_set_time(&a, time);
|
|
||||||
lv_anim_set_delay(&a, delay);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay)
|
|
||||||
{
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, obj);
|
|
||||||
lv_anim_set_values(&a, lv_obj_get_style_opa(obj, 0), LV_OPA_TRANSP);
|
|
||||||
lv_anim_set_exec_cb(&a, fade_anim_cb);
|
|
||||||
lv_anim_set_time(&a, time);
|
|
||||||
lv_anim_set_delay(&a, delay);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
return selector & 0xFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
return selector & 0xFF0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lv_text_align_t lv_obj_calculate_style_text_align(const struct _lv_obj_t * obj, lv_part_t part, const char * txt)
|
|
||||||
{
|
|
||||||
lv_text_align_t align = lv_obj_get_style_text_align(obj, part);
|
|
||||||
lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, part);
|
|
||||||
lv_bidi_calculate_align(&align, &base_dir, txt);
|
|
||||||
return align;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the local style of an object for a given part and for a given state.
|
|
||||||
* If the local style for the part-state pair doesn't exist allocate and return it.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param selector OR-ed value of parts and state for which the style should be get
|
|
||||||
* @return pointer to the local style
|
|
||||||
*/
|
|
||||||
static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_local &&
|
|
||||||
obj->styles[i].selector == selector) {
|
|
||||||
return obj->styles[i].style;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->style_cnt++;
|
|
||||||
obj->styles = lv_mem_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t));
|
|
||||||
LV_ASSERT_MALLOC(obj->styles);
|
|
||||||
|
|
||||||
for(i = obj->style_cnt - 1; i > 0 ; i--) {
|
|
||||||
/*Copy only normal styles (not local and transition).
|
|
||||||
*The new local style will be added as the last local style*/
|
|
||||||
if(obj->styles[i - 1].is_local || obj->styles[i - 1].is_trans) break;
|
|
||||||
obj->styles[i] = obj->styles[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_memset_00(&obj->styles[i], sizeof(_lv_obj_style_t));
|
|
||||||
obj->styles[i].style = lv_mem_alloc(sizeof(lv_style_t));
|
|
||||||
lv_style_init(obj->styles[i].style);
|
|
||||||
obj->styles[i].is_local = 1;
|
|
||||||
obj->styles[i].selector = selector;
|
|
||||||
return obj->styles[i].style;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the transition style of an object for a given part and for a given state.
|
|
||||||
* If the transition style for the part-state pair doesn't exist allocate and return it.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param selector OR-ed value of parts and state for which the style should be get
|
|
||||||
* @return pointer to the transition style
|
|
||||||
*/
|
|
||||||
static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans && obj->styles[i].selector == selector) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Already have a transition style for it*/
|
|
||||||
if(i != obj->style_cnt) return &obj->styles[i];
|
|
||||||
|
|
||||||
obj->style_cnt++;
|
|
||||||
obj->styles = lv_mem_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t));
|
|
||||||
|
|
||||||
for(i = obj->style_cnt - 1; i > 0 ; i--) {
|
|
||||||
obj->styles[i] = obj->styles[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_memset_00(&obj->styles[0], sizeof(_lv_obj_style_t));
|
|
||||||
obj->styles[0].style = lv_mem_alloc(sizeof(lv_style_t));
|
|
||||||
lv_style_init(obj->styles[0].style);
|
|
||||||
obj->styles[0].is_trans = 1;
|
|
||||||
obj->styles[0].selector = selector;
|
|
||||||
return &obj->styles[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v)
|
|
||||||
{
|
|
||||||
uint8_t group = 1 << _lv_style_get_prop_group(prop);
|
|
||||||
int32_t weight = -1;
|
|
||||||
lv_state_t state = obj->state;
|
|
||||||
lv_state_t state_inv = ~state;
|
|
||||||
lv_style_value_t value_tmp;
|
|
||||||
bool skip_trans = obj->skip_trans;
|
|
||||||
uint32_t i;
|
|
||||||
lv_style_res_t found;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
_lv_obj_style_t * obj_style = &obj->styles[i];
|
|
||||||
if(obj_style->is_trans == false) break;
|
|
||||||
if(skip_trans) continue;
|
|
||||||
|
|
||||||
lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector);
|
|
||||||
|
|
||||||
if(part_act != part) continue;
|
|
||||||
if((obj_style->style->has_group & group) == 0) continue;
|
|
||||||
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
|
||||||
if(found == LV_STYLE_RES_FOUND) {
|
|
||||||
*v = value_tmp;
|
|
||||||
return LV_STYLE_RES_FOUND;
|
|
||||||
}
|
|
||||||
else if(found == LV_STYLE_RES_INHERIT) {
|
|
||||||
return LV_STYLE_RES_INHERIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(; i < obj->style_cnt; i++) {
|
|
||||||
if((obj->styles[i].style->has_group & group) == 0) continue;
|
|
||||||
_lv_obj_style_t * obj_style = &obj->styles[i];
|
|
||||||
lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector);
|
|
||||||
lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector);
|
|
||||||
if(part_act != part) continue;
|
|
||||||
|
|
||||||
/*Be sure the style not specifies other state than the requested.
|
|
||||||
*E.g. For HOVER+PRESS object state, HOVER style only is OK, but HOVER+FOCUS style is not*/
|
|
||||||
if((state_act & state_inv)) continue;
|
|
||||||
|
|
||||||
/*Check only better candidates*/
|
|
||||||
if(state_act <= weight) continue;
|
|
||||||
|
|
||||||
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
|
||||||
|
|
||||||
if(found == LV_STYLE_RES_FOUND) {
|
|
||||||
if(state_act == state) {
|
|
||||||
*v = value_tmp;
|
|
||||||
return LV_STYLE_RES_FOUND;
|
|
||||||
}
|
|
||||||
if(weight < state_act) {
|
|
||||||
weight = state_act;
|
|
||||||
*v = value_tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(found == LV_STYLE_RES_INHERIT) {
|
|
||||||
return LV_STYLE_RES_INHERIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(weight >= 0) {
|
|
||||||
*v = value_tmp;
|
|
||||||
return LV_STYLE_RES_FOUND;
|
|
||||||
}
|
|
||||||
else return LV_STYLE_RES_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh the style of all children of an object. (Called recursively)
|
|
||||||
* @param style refresh objects only with this
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
static void report_style_change_core(void * style, lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(style == NULL || obj->styles[i].style == style) {
|
|
||||||
lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
report_style_change_core(style, obj->spec_attr->children[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively refresh the style of the children. Go deeper until a not NULL style is found
|
|
||||||
* because the NULL styles are inherited from the parent
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
static void refresh_children_style(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
|
||||||
for(i = 0; i < child_cnt; i++) {
|
|
||||||
lv_obj_t * child = obj->spec_attr->children[i];
|
|
||||||
lv_obj_invalidate(child);
|
|
||||||
lv_event_send(child, LV_EVENT_STYLE_CHANGED, NULL);
|
|
||||||
lv_obj_invalidate(child);
|
|
||||||
|
|
||||||
refresh_children_style(child); /*Check children too*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the transition from object's part's property.
|
|
||||||
* - Remove the transition from `_lv_obj_style_trans_ll` and free it
|
|
||||||
* - Delete pending transitions
|
|
||||||
* @param obj pointer to an object which transition(s) should be removed
|
|
||||||
* @param part a part of object or 0xFF to remove from all parts
|
|
||||||
* @param prop a property or 0xFF to remove all properties
|
|
||||||
* @param tr_limit delete transitions only "older" than this. `NULL` if not used
|
|
||||||
*/
|
|
||||||
static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit)
|
|
||||||
{
|
|
||||||
trans_t * tr;
|
|
||||||
trans_t * tr_prev;
|
|
||||||
bool removed = false;
|
|
||||||
tr = _lv_ll_get_tail(&LV_GC_ROOT(_lv_obj_style_trans_ll));
|
|
||||||
while(tr != NULL) {
|
|
||||||
if(tr == tr_limit) break;
|
|
||||||
|
|
||||||
/*'tr' might be deleted, so get the next object while 'tr' is valid*/
|
|
||||||
tr_prev = _lv_ll_get_prev(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
|
|
||||||
|
|
||||||
if(tr->obj == obj && (part == tr->selector || part == LV_PART_ANY) && (prop == tr->prop || prop == LV_STYLE_PROP_ANY)) {
|
|
||||||
/*Remove any transitioned properties from the trans. style
|
|
||||||
*to allow changing it by normal styles*/
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans && (part == LV_PART_ANY || obj->styles[i].selector == part)) {
|
|
||||||
lv_style_remove_prop(obj->styles[i].style, tr->prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Free the transition descriptor too*/
|
|
||||||
lv_anim_del(tr, NULL);
|
|
||||||
_lv_ll_remove(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
|
|
||||||
lv_mem_free(tr);
|
|
||||||
removed = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
tr = tr_prev;
|
|
||||||
}
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void trans_anim_cb(void * _tr, int32_t v)
|
|
||||||
{
|
|
||||||
trans_t * tr = _tr;
|
|
||||||
lv_obj_t * obj = tr->obj;
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans == 0 || obj->styles[i].selector != tr->selector) continue;
|
|
||||||
|
|
||||||
lv_style_value_t value_final;
|
|
||||||
switch(tr->prop) {
|
|
||||||
|
|
||||||
case LV_STYLE_BORDER_SIDE:
|
|
||||||
case LV_STYLE_BORDER_POST:
|
|
||||||
case LV_STYLE_BLEND_MODE:
|
|
||||||
if(v < 255) value_final.num = tr->start_value.num;
|
|
||||||
else value_final.num = tr->end_value.num;
|
|
||||||
break;
|
|
||||||
case LV_STYLE_TRANSITION:
|
|
||||||
case LV_STYLE_TEXT_FONT:
|
|
||||||
if(v < 255) value_final.ptr = tr->start_value.ptr;
|
|
||||||
else value_final.ptr = tr->end_value.ptr;
|
|
||||||
break;
|
|
||||||
case LV_STYLE_COLOR_FILTER_DSC:
|
|
||||||
if(tr->start_value.ptr == NULL) value_final.ptr = tr->end_value.ptr;
|
|
||||||
else if(tr->end_value.ptr == NULL) value_final.ptr = tr->start_value.ptr;
|
|
||||||
else if(v < 128) value_final.ptr = tr->start_value.ptr;
|
|
||||||
else value_final.ptr = tr->end_value.ptr;
|
|
||||||
break;
|
|
||||||
case LV_STYLE_BG_COLOR:
|
|
||||||
case LV_STYLE_BORDER_COLOR:
|
|
||||||
case LV_STYLE_TEXT_COLOR:
|
|
||||||
case LV_STYLE_SHADOW_COLOR:
|
|
||||||
case LV_STYLE_OUTLINE_COLOR:
|
|
||||||
case LV_STYLE_IMG_RECOLOR:
|
|
||||||
if(v <= 0) value_final.color = tr->start_value.color;
|
|
||||||
else if(v >= 255) value_final.color = tr->end_value.color;
|
|
||||||
else value_final.color = lv_color_mix(tr->end_value.color, tr->start_value.color, v);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if(v == 0) value_final.num = tr->start_value.num;
|
|
||||||
else if(v == 255) value_final.num = tr->end_value.num;
|
|
||||||
else value_final.num = tr->start_value.num + ((int32_t)((int32_t)(tr->end_value.num - tr->start_value.num) * v) >> 8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_style_value_t old_value;
|
|
||||||
bool refr = true;
|
|
||||||
if(lv_style_get_prop(obj->styles[i].style, tr->prop, &old_value)) {
|
|
||||||
if(value_final.ptr == old_value.ptr && value_final.color.full == old_value.color.full &&
|
|
||||||
value_final.num == old_value.num) {
|
|
||||||
refr = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lv_style_set_prop(obj->styles[i].style, tr->prop, value_final);
|
|
||||||
if(refr) lv_obj_refresh_style(tr->obj, tr->selector, tr->prop);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void trans_anim_start_cb(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
trans_t * tr = a->var;
|
|
||||||
|
|
||||||
lv_part_t part = lv_obj_style_get_selector_part(tr->selector);
|
|
||||||
tr->start_value = lv_obj_get_style_prop(tr->obj, part, tr->prop);
|
|
||||||
|
|
||||||
/*Init prop to an invalid values to be sure `trans_del` won't delete this added `tr`*/
|
|
||||||
lv_style_prop_t prop_tmp = tr->prop;
|
|
||||||
tr->prop = LV_STYLE_PROP_INV;
|
|
||||||
|
|
||||||
/*Delete the related transitions if any*/
|
|
||||||
trans_del(tr->obj, part, prop_tmp, tr);
|
|
||||||
|
|
||||||
tr->prop = prop_tmp;
|
|
||||||
|
|
||||||
_lv_obj_style_t * style_trans = get_trans_style(tr->obj, tr->selector);
|
|
||||||
lv_style_set_prop(style_trans->style, tr->prop, tr->start_value); /*Be sure `trans_style` has a valid value*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void trans_anim_ready_cb(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
trans_t * tr = a->var;
|
|
||||||
lv_obj_t * obj = tr->obj;
|
|
||||||
lv_style_prop_t prop = tr->prop;
|
|
||||||
|
|
||||||
/*Remove the transitioned property from trans. style
|
|
||||||
*if there no more transitions for this property
|
|
||||||
*It allows changing it by normal styles*/
|
|
||||||
bool running = false;
|
|
||||||
trans_t * tr_i;
|
|
||||||
_LV_LL_READ(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr_i) {
|
|
||||||
if(tr_i != tr && tr_i->obj == tr->obj && tr_i->selector == tr->selector && tr_i->prop == tr->prop) {
|
|
||||||
running = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!running) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
|
||||||
if(obj->styles[i].is_trans && obj->styles[i].selector == tr->selector) {
|
|
||||||
_lv_ll_remove(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
|
|
||||||
lv_mem_free(tr);
|
|
||||||
|
|
||||||
_lv_obj_style_t * obj_style = &obj->styles[i];
|
|
||||||
lv_style_remove_prop(obj_style->style, prop);
|
|
||||||
|
|
||||||
if(lv_style_is_empty(obj->styles[i].style)) {
|
|
||||||
lv_obj_remove_style(obj, obj_style->style, obj_style->selector);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static lv_layer_type_t calculate_layer_type(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(lv_obj_get_style_transform_angle(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM;
|
|
||||||
if(lv_obj_get_style_transform_zoom(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM;
|
|
||||||
if(lv_obj_get_style_opa(obj, 0) != LV_OPA_COVER) return LV_LAYER_TYPE_SIMPLE;
|
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
|
||||||
if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_LAYER_TYPE_SIMPLE;
|
|
||||||
#endif
|
|
||||||
return LV_LAYER_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fade_anim_cb(void * obj, int32_t v)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_opa(obj, v, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fade_in_anim_ready(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,248 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_style.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_STYLE_H
|
|
||||||
#define LV_OBJ_STYLE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "../misc/lv_bidi.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
/*Can't include lv_obj.h because it includes this header file*/
|
|
||||||
struct _lv_obj_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
_LV_STYLE_STATE_CMP_SAME, /*The style properties in the 2 states are identical*/
|
|
||||||
_LV_STYLE_STATE_CMP_DIFF_REDRAW, /*The differences can be shown with a simple redraw*/
|
|
||||||
_LV_STYLE_STATE_CMP_DIFF_DRAW_PAD, /*The differences can be shown with a simple redraw*/
|
|
||||||
_LV_STYLE_STATE_CMP_DIFF_LAYOUT, /*The differences can be shown with a simple redraw*/
|
|
||||||
} _lv_style_state_cmp_t;
|
|
||||||
|
|
||||||
typedef uint32_t lv_style_selector_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lv_style_t * style;
|
|
||||||
uint32_t selector : 24;
|
|
||||||
uint32_t is_local : 1;
|
|
||||||
uint32_t is_trans : 1;
|
|
||||||
} _lv_obj_style_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t time;
|
|
||||||
uint16_t delay;
|
|
||||||
lv_style_selector_t selector;
|
|
||||||
lv_style_prop_t prop;
|
|
||||||
lv_anim_path_cb_t path_cb;
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
void * user_data;
|
|
||||||
#endif
|
|
||||||
} _lv_obj_style_transition_dsc_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object related style manager module.
|
|
||||||
* Called by LVGL in `lv_init()`
|
|
||||||
*/
|
|
||||||
void _lv_obj_style_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a style to an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param style pointer to a style to add
|
|
||||||
* @param selector OR-ed value of parts and state to which the style should be added
|
|
||||||
* @example lv_obj_add_style(btn, &style_btn, 0); //Default button style
|
|
||||||
* @example lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed
|
|
||||||
*/
|
|
||||||
void lv_obj_add_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a style to an object.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param style pointer to a style to remove. Can be NULL to check only the selector
|
|
||||||
* @param selector OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
|
|
||||||
* @example lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style
|
|
||||||
* @example lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part
|
|
||||||
* @example lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles
|
|
||||||
*/
|
|
||||||
void lv_obj_remove_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all styles from an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
static inline void lv_obj_remove_style_all(struct _lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify all object if a style is modified
|
|
||||||
* @param style pointer to a style. Only the objects with this style will be notified
|
|
||||||
* (NULL to notify all objects)
|
|
||||||
*/
|
|
||||||
void lv_obj_report_style_change(lv_style_t * style);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify an object and its children about its style is modified.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part the part whose style was changed. E.g. `LV_PART_ANY`, `LV_PART_MAIN`
|
|
||||||
* @param prop `LV_STYLE_PROP_ANY` or an `LV_STYLE_...` property.
|
|
||||||
* It is used to optimize what needs to be refreshed.
|
|
||||||
* `LV_STYLE_PROP_INV` to perform only a style cache update
|
|
||||||
*/
|
|
||||||
void lv_obj_refresh_style(struct _lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable automatic style refreshing when a new style is added/removed to/from an object
|
|
||||||
* or any other style change happens.
|
|
||||||
* @param en true: enable refreshing; false: disable refreshing
|
|
||||||
*/
|
|
||||||
void lv_obj_enable_style_refresh(bool en);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of a style property. The current state of the object will be considered.
|
|
||||||
* Inherited properties will be inherited.
|
|
||||||
* If a property is not set a default value will be returned.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param part a part from which the property should be get
|
|
||||||
* @param prop the property to get
|
|
||||||
* @return the value of the property.
|
|
||||||
* Should be read from the correct field of the `lv_style_value_t` according to the type of the property.
|
|
||||||
*/
|
|
||||||
lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set local style property on an object's part and state.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param prop the property
|
|
||||||
* @param value value of the property. The correct element should be set according to the type of the property
|
|
||||||
* @param selector OR-ed value of parts and state for which the style should be set
|
|
||||||
*/
|
|
||||||
void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
|
|
||||||
lv_style_selector_t selector);
|
|
||||||
|
|
||||||
void lv_obj_set_local_style_prop_meta(struct _lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta,
|
|
||||||
lv_style_selector_t selector);
|
|
||||||
|
|
||||||
lv_style_res_t lv_obj_get_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
|
||||||
lv_style_selector_t selector);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a local style property from a part of an object with a given state.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param prop a style property to remove.
|
|
||||||
* @param selector OR-ed value of parts and state for which the style should be removed
|
|
||||||
* @return true the property was found and removed; false: the property was not found
|
|
||||||
*/
|
|
||||||
bool lv_obj_remove_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for color filtering
|
|
||||||
*/
|
|
||||||
lv_style_value_t _lv_obj_style_apply_color_filter(const struct _lv_obj_t * obj, uint32_t part, lv_style_value_t v);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally to create a style transition
|
|
||||||
* @param obj
|
|
||||||
* @param part
|
|
||||||
* @param prev_state
|
|
||||||
* @param new_state
|
|
||||||
* @param tr
|
|
||||||
*/
|
|
||||||
void _lv_obj_style_create_transition(struct _lv_obj_t * obj, lv_part_t part, lv_state_t prev_state,
|
|
||||||
lv_state_t new_state, const _lv_obj_style_transition_dsc_t * tr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally to compare the appearance of an object in 2 states
|
|
||||||
* @param obj
|
|
||||||
* @param state1
|
|
||||||
* @param state2
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
_lv_style_state_cmp_t _lv_obj_style_state_compare(struct _lv_obj_t * obj, lv_state_t state1, lv_state_t state2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fade in an an object and all its children.
|
|
||||||
* @param obj the object to fade in
|
|
||||||
* @param time time of fade
|
|
||||||
* @param delay delay to start the animation
|
|
||||||
*/
|
|
||||||
void lv_obj_fade_in(struct _lv_obj_t * obj, uint32_t time, uint32_t delay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fade out an an object and all its children.
|
|
||||||
* @param obj the object to fade out
|
|
||||||
* @param time time of fade
|
|
||||||
* @param delay delay to start the animation
|
|
||||||
*/
|
|
||||||
void lv_obj_fade_out(struct _lv_obj_t * obj, uint32_t time, uint32_t delay);
|
|
||||||
|
|
||||||
lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector);
|
|
||||||
|
|
||||||
lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector);
|
|
||||||
|
|
||||||
#include "lv_obj_style_gen.h"
|
|
||||||
|
|
||||||
static inline void lv_obj_set_style_pad_all(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_pad_left(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_right(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_top(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_bottom(obj, value, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lv_obj_set_style_pad_hor(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_pad_left(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_right(obj, value, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lv_obj_set_style_pad_ver(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_pad_top(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_bottom(obj, value, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lv_obj_set_style_pad_gap(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_pad_row(obj, value, selector);
|
|
||||||
lv_obj_set_style_pad_column(obj, value, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lv_obj_set_style_size(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_obj_set_style_width(obj, value, selector);
|
|
||||||
lv_obj_set_style_height(obj, value, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_text_align_t lv_obj_calculate_style_text_align(const struct _lv_obj_t * obj, lv_part_t part, const char * txt);
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_STYLE_H*/
|
|
@ -1,673 +0,0 @@
|
|||||||
#include "lv_obj.h"
|
|
||||||
|
|
||||||
void lv_obj_set_style_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_min_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MIN_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_max_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MAX_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_HEIGHT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_min_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MIN_HEIGHT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_max_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MAX_HEIGHT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_X, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_Y, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_align(struct _lv_obj_t * obj, lv_align_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ALIGN, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_HEIGHT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_translate_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_X, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_translate_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_Y, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_zoom(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_ZOOM, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_angle(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_ANGLE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_pivot_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_PIVOT_X, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transform_pivot_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_PIVOT_Y, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_top(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_TOP, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_bottom(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_BOTTOM, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_left(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_LEFT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_right(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_RIGHT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_row(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_ROW, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_pad_column(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_COLUMN, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_grad_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_grad_dir(struct _lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_DIR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_main_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_MAIN_STOP, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_grad_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_STOP, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_grad(struct _lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_dither_mode(struct _lv_obj_t * obj, lv_dither_mode_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_DITHER_MODE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMG_SRC, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_img_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMG_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_img_recolor(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMG_RECOLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_img_recolor_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMG_RECOLOR_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_bg_img_tiled(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMG_TILED, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_border_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_border_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_border_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_border_side(struct _lv_obj_t * obj, lv_border_side_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_SIDE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_border_post(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_POST, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_outline_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_outline_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_outline_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_outline_pad(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_PAD, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_ofs_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OFS_X, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_ofs_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OFS_Y, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_spread(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_SPREAD, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_shadow_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_img_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMG_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_img_recolor(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMG_RECOLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_img_recolor_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMG_RECOLOR_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_dash_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_DASH_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_dash_gap(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_DASH_GAP, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_rounded(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_ROUNDED, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_line_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_arc_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_WIDTH, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_arc_rounded(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_ROUNDED, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_arc_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_arc_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_arc_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_IMG_SRC, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.color = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_COLOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_font(struct _lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_FONT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_letter_space(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_LETTER_SPACE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_line_space(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_LINE_SPACE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_decor(struct _lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_DECOR, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_text_align(struct _lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_ALIGN, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_radius(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_RADIUS, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_CLIP_CORNER, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_DSC, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_OPA, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM_TIME, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM_SPEED, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.ptr = value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSITION, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BLEND_MODE, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_layout(struct _lv_obj_t * obj, uint16_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LAYOUT, v, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_base_dir(struct _lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = {
|
|
||||||
.num = (int32_t)value
|
|
||||||
};
|
|
||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BASE_DIR, v, selector);
|
|
||||||
}
|
|
@ -1,648 +0,0 @@
|
|||||||
static inline lv_coord_t lv_obj_get_style_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_min_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_max_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_height(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_HEIGHT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_min_height(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_HEIGHT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_max_height(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_HEIGHT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_x(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_X);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_y(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_Y);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_align_t lv_obj_get_style_align(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ALIGN);
|
|
||||||
return (lv_align_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_height(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_HEIGHT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_translate_x(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_X);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_translate_y(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_Y);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_zoom(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_ZOOM);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_angle(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_ANGLE);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_pivot_x(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_X);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_transform_pivot_y(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_Y);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_top(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_TOP);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_bottom(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_BOTTOM);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_left(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_LEFT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_right(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_RIGHT);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_row(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_ROW);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_pad_column(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_COLUMN);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_bg_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_grad_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_DIR);
|
|
||||||
return (lv_grad_dir_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_bg_main_stop(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_STOP);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_bg_grad_stop(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_STOP);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD);
|
|
||||||
return (const lv_grad_dsc_t *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_dither_mode_t lv_obj_get_style_bg_dither_mode(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_DITHER_MODE);
|
|
||||||
return (lv_dither_mode_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const void * lv_obj_get_style_bg_img_src(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_SRC);
|
|
||||||
return (const void *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_bg_img_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_img_recolor(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_RECOLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_RECOLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_bg_img_recolor_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_RECOLOR_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lv_obj_get_style_bg_img_tiled(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_TILED);
|
|
||||||
return (bool)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_border_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_border_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_border_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_border_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_border_side_t lv_obj_get_style_border_side(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_SIDE);
|
|
||||||
return (lv_border_side_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lv_obj_get_style_border_post(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_POST);
|
|
||||||
return (bool)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_outline_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_outline_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_outline_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_outline_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_outline_pad(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_PAD);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_shadow_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_shadow_ofs_x(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFS_X);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_shadow_ofs_y(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFS_Y);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_shadow_spread(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_SPREAD);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_shadow_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_shadow_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_img_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_img_recolor(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_RECOLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_RECOLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_img_recolor_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_RECOLOR_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_line_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_line_dash_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_line_dash_gap(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_GAP);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lv_obj_get_style_line_rounded(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_ROUNDED);
|
|
||||||
return (bool)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_line_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_line_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_line_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_arc_width(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_WIDTH);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lv_obj_get_style_arc_rounded(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_ROUNDED);
|
|
||||||
return (bool)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_arc_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_arc_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_arc_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const void * lv_obj_get_style_arc_img_src(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_IMG_SRC);
|
|
||||||
return (const void *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_text_color(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR);
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_text_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR));
|
|
||||||
return v.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_text_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const lv_font_t * lv_obj_get_style_text_font(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_FONT);
|
|
||||||
return (const lv_font_t *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_text_letter_space(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LETTER_SPACE);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_text_line_space(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LINE_SPACE);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_text_decor_t lv_obj_get_style_text_decor(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_DECOR);
|
|
||||||
return (lv_text_decor_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_text_align_t lv_obj_get_style_text_align(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_ALIGN);
|
|
||||||
return (lv_text_align_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_coord_t lv_obj_get_style_radius(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RADIUS);
|
|
||||||
return (lv_coord_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lv_obj_get_style_clip_corner(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_CLIP_CORNER);
|
|
||||||
return (bool)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC);
|
|
||||||
return (const lv_color_filter_dsc_t *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_opa_t lv_obj_get_style_color_filter_opa(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_OPA);
|
|
||||||
return (lv_opa_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const lv_anim_t * lv_obj_get_style_anim(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM);
|
|
||||||
return (const lv_anim_t *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t lv_obj_get_style_anim_time(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_TIME);
|
|
||||||
return (uint32_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t lv_obj_get_style_anim_speed(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_SPEED);
|
|
||||||
return (uint32_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSITION);
|
|
||||||
return (const lv_style_transition_dsc_t *)v.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLEND_MODE);
|
|
||||||
return (lv_blend_mode_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t lv_obj_get_style_layout(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LAYOUT);
|
|
||||||
return (uint16_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline lv_base_dir_t lv_obj_get_style_base_dir(const struct _lv_obj_t * obj, uint32_t part)
|
|
||||||
{
|
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BASE_DIR);
|
|
||||||
return (lv_base_dir_t)v.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_style_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_min_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_max_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_min_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_max_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_align(struct _lv_obj_t * obj, lv_align_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_height(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_translate_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_translate_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_zoom(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_angle(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_pivot_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transform_pivot_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_top(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_bottom(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_left(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_right(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_row(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_pad_column(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_grad_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_grad_dir(struct _lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_main_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_grad_stop(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_grad(struct _lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_dither_mode(struct _lv_obj_t * obj, lv_dither_mode_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_img_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_img_recolor(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_img_recolor_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_bg_img_tiled(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_border_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_border_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_border_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_border_side(struct _lv_obj_t * obj, lv_border_side_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_border_post(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_outline_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_outline_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_outline_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_outline_pad(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_ofs_x(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_ofs_y(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_spread(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_shadow_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_img_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_img_recolor(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_img_recolor_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_dash_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_dash_gap(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_rounded(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_line_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_arc_width(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_arc_rounded(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_arc_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_arc_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_arc_img_src(struct _lv_obj_t * obj, const void * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_color(struct _lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_font(struct _lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_letter_space(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_line_space(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_decor(struct _lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_text_align(struct _lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_radius(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_layout(struct _lv_obj_t * obj, uint16_t value, lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_base_dir(struct _lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector);
|
|
@ -1,452 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_obj_tree.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include "lv_indev.h"
|
|
||||||
#include "../misc/lv_anim.h"
|
|
||||||
#include "../misc/lv_gc.h"
|
|
||||||
#include "../misc/lv_async.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define MY_CLASS &lv_obj_class
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void lv_obj_del_async_cb(void * obj);
|
|
||||||
static void obj_del_core(lv_obj_t * obj);
|
|
||||||
static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb, void * user_data);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_obj_del(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_LOG_TRACE("begin (delete %p)", (void *)obj);
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
|
||||||
if(par) {
|
|
||||||
lv_obj_scrollbar_invalidate(par);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_disp_t * disp = NULL;
|
|
||||||
bool act_scr_del = false;
|
|
||||||
if(par == NULL) {
|
|
||||||
disp = lv_obj_get_disp(obj);
|
|
||||||
if(!disp) return; /*Shouldn't happen*/
|
|
||||||
if(disp->act_scr == obj) act_scr_del = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj_del_core(obj);
|
|
||||||
|
|
||||||
/*Call the ancestor's event handler to the parent to notify it about the child delete*/
|
|
||||||
if(par) {
|
|
||||||
lv_obj_update_layout(par);
|
|
||||||
lv_obj_readjust_scroll(par, LV_ANIM_OFF);
|
|
||||||
lv_obj_scrollbar_invalidate(par);
|
|
||||||
lv_event_send(par, LV_EVENT_CHILD_CHANGED, NULL);
|
|
||||||
lv_event_send(par, LV_EVENT_CHILD_DELETED, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Handle if the active screen was deleted*/
|
|
||||||
if(act_scr_del) {
|
|
||||||
LV_LOG_WARN("the active screen was deleted");
|
|
||||||
disp->act_scr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_ASSERT_MEM_INTEGRITY();
|
|
||||||
LV_LOG_TRACE("finished (delete %p)", (void *)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_clean(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_LOG_TRACE("begin (delete %p)", (void *)obj);
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
lv_obj_t * child = lv_obj_get_child(obj, 0);
|
|
||||||
while(child) {
|
|
||||||
obj_del_core(child);
|
|
||||||
child = lv_obj_get_child(obj, 0);
|
|
||||||
}
|
|
||||||
/*Just to remove scroll animations if any*/
|
|
||||||
lv_obj_scroll_to(obj, 0, 0, LV_ANIM_OFF);
|
|
||||||
if(obj->spec_attr) {
|
|
||||||
obj->spec_attr->scroll.x = 0;
|
|
||||||
obj->spec_attr->scroll.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_ASSERT_MEM_INTEGRITY();
|
|
||||||
|
|
||||||
LV_LOG_TRACE("finished (delete %p)", (void *)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_del_delayed(lv_obj_t * obj, uint32_t delay_ms)
|
|
||||||
{
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, obj);
|
|
||||||
lv_anim_set_exec_cb(&a, NULL);
|
|
||||||
lv_anim_set_time(&a, 1);
|
|
||||||
lv_anim_set_delay(&a, delay_ms);
|
|
||||||
lv_anim_set_ready_cb(&a, lv_obj_del_anim_ready_cb);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_del_anim_ready_cb(lv_anim_t * a)
|
|
||||||
{
|
|
||||||
lv_obj_del(a->var);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_del_async(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
lv_async_call(lv_obj_del_async_cb, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
LV_ASSERT_OBJ(parent, MY_CLASS);
|
|
||||||
|
|
||||||
if(obj->parent == NULL) {
|
|
||||||
LV_LOG_WARN("Can't set the parent of a screen");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent == NULL) {
|
|
||||||
LV_LOG_WARN("Can't set parent == NULL to an object");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
|
|
||||||
lv_obj_allocate_spec_attr(parent);
|
|
||||||
|
|
||||||
lv_obj_t * old_parent = obj->parent;
|
|
||||||
/*Remove the object from the old parent's child list*/
|
|
||||||
int32_t i;
|
|
||||||
for(i = lv_obj_get_index(obj); i <= (int32_t)lv_obj_get_child_cnt(old_parent) - 2; i++) {
|
|
||||||
old_parent->spec_attr->children[i] = old_parent->spec_attr->children[i + 1];
|
|
||||||
}
|
|
||||||
old_parent->spec_attr->child_cnt--;
|
|
||||||
if(old_parent->spec_attr->child_cnt) {
|
|
||||||
old_parent->spec_attr->children = lv_mem_realloc(old_parent->spec_attr->children,
|
|
||||||
old_parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_mem_free(old_parent->spec_attr->children);
|
|
||||||
old_parent->spec_attr->children = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Add the child to the new parent as the last (newest child)*/
|
|
||||||
parent->spec_attr->child_cnt++;
|
|
||||||
parent->spec_attr->children = lv_mem_realloc(parent->spec_attr->children,
|
|
||||||
parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
|
|
||||||
parent->spec_attr->children[lv_obj_get_child_cnt(parent) - 1] = obj;
|
|
||||||
|
|
||||||
obj->parent = parent;
|
|
||||||
|
|
||||||
/*Notify the original parent because one of its children is lost*/
|
|
||||||
lv_obj_readjust_scroll(old_parent, LV_ANIM_OFF);
|
|
||||||
lv_obj_scrollbar_invalidate(old_parent);
|
|
||||||
lv_event_send(old_parent, LV_EVENT_CHILD_CHANGED, obj);
|
|
||||||
lv_event_send(old_parent, LV_EVENT_CHILD_DELETED, NULL);
|
|
||||||
|
|
||||||
/*Notify the new parent about the child*/
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj);
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CREATED, NULL);
|
|
||||||
|
|
||||||
lv_obj_mark_layout_as_dirty(obj);
|
|
||||||
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_move_to_index(lv_obj_t * obj, int32_t index)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(index < 0) {
|
|
||||||
index = lv_obj_get_child_cnt(lv_obj_get_parent(obj)) + index;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32_t old_index = lv_obj_get_index(obj);
|
|
||||||
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
|
||||||
|
|
||||||
if(index < 0) return;
|
|
||||||
if(index >= (int32_t) lv_obj_get_child_cnt(parent)) return;
|
|
||||||
if(index == old_index) return;
|
|
||||||
|
|
||||||
int32_t i = old_index;
|
|
||||||
if(index < old_index) {
|
|
||||||
while(i > index) {
|
|
||||||
parent->spec_attr->children[i] = parent->spec_attr->children[i - 1];
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while(i < index) {
|
|
||||||
parent->spec_attr->children[i] = parent->spec_attr->children[i + 1];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent->spec_attr->children[index] = obj;
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CHANGED, NULL);
|
|
||||||
lv_obj_invalidate(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj1, MY_CLASS);
|
|
||||||
LV_ASSERT_OBJ(obj2, MY_CLASS);
|
|
||||||
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj1);
|
|
||||||
lv_obj_t * parent2 = lv_obj_get_parent(obj2);
|
|
||||||
|
|
||||||
uint_fast32_t index1 = lv_obj_get_index(obj1);
|
|
||||||
uint_fast32_t index2 = lv_obj_get_index(obj2);
|
|
||||||
|
|
||||||
lv_event_send(parent2, LV_EVENT_CHILD_DELETED, obj2);
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_DELETED, obj1);
|
|
||||||
|
|
||||||
parent->spec_attr->children[index1] = obj2;
|
|
||||||
parent2->spec_attr->children[index2] = obj1;
|
|
||||||
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj2);
|
|
||||||
lv_event_send(parent, LV_EVENT_CHILD_CREATED, obj2);
|
|
||||||
lv_event_send(parent2, LV_EVENT_CHILD_CHANGED, obj1);
|
|
||||||
lv_event_send(parent2, LV_EVENT_CHILD_CREATED, obj1);
|
|
||||||
|
|
||||||
lv_obj_invalidate(parent);
|
|
||||||
|
|
||||||
if(parent != parent2) {
|
|
||||||
lv_obj_invalidate(parent2);
|
|
||||||
}
|
|
||||||
lv_group_swap_obj(obj1, obj2);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
const lv_obj_t * par = obj;
|
|
||||||
const lv_obj_t * act_par;
|
|
||||||
|
|
||||||
do {
|
|
||||||
act_par = par;
|
|
||||||
par = lv_obj_get_parent(act_par);
|
|
||||||
} while(par != NULL);
|
|
||||||
|
|
||||||
return (lv_obj_t *)act_par;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
const lv_obj_t * scr;
|
|
||||||
|
|
||||||
if(obj->parent == NULL) scr = obj; /*`obj` is a screen*/
|
|
||||||
else scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
|
|
||||||
|
|
||||||
lv_disp_t * d;
|
|
||||||
_LV_LL_READ(&LV_GC_ROOT(_lv_disp_ll), d) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < d->screen_cnt; i++) {
|
|
||||||
if(d->screens[i] == scr) return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_LOG_WARN("No screen found");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(obj == NULL) return NULL;
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
return obj->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t id)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
if(obj->spec_attr == NULL) return NULL;
|
|
||||||
|
|
||||||
uint32_t idu;
|
|
||||||
if(id < 0) {
|
|
||||||
id = obj->spec_attr->child_cnt + id;
|
|
||||||
if(id < 0) return NULL;
|
|
||||||
idu = (uint32_t) id;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
idu = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(idu >= obj->spec_attr->child_cnt) return NULL;
|
|
||||||
else return obj->spec_attr->children[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
if(obj->spec_attr == NULL) return 0;
|
|
||||||
return obj->spec_attr->child_cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lv_obj_get_index(const lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
|
||||||
if(parent == NULL) return 0;
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
|
|
||||||
if(lv_obj_get_child(parent, i) == obj) return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0xFFFFFFFF; /*Shouldn't happen*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data)
|
|
||||||
{
|
|
||||||
walk_core(start_obj, cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void lv_obj_del_async_cb(void * obj)
|
|
||||||
{
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
||||||
|
|
||||||
lv_obj_del(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void obj_del_core(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
/*Let the user free the resources used in `LV_EVENT_DELETE`*/
|
|
||||||
lv_res_t res = lv_event_send(obj, LV_EVENT_DELETE, NULL);
|
|
||||||
if(res == LV_RES_INV) return;
|
|
||||||
|
|
||||||
/*Recursively delete the children*/
|
|
||||||
lv_obj_t * child = lv_obj_get_child(obj, 0);
|
|
||||||
while(child) {
|
|
||||||
obj_del_core(child);
|
|
||||||
child = lv_obj_get_child(obj, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_group_t * group = lv_obj_get_group(obj);
|
|
||||||
|
|
||||||
/*Reset all input devices if the object to delete is used*/
|
|
||||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
|
||||||
while(indev) {
|
|
||||||
if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) {
|
|
||||||
lv_indev_reset(indev, obj);
|
|
||||||
}
|
|
||||||
if(indev->proc.types.pointer.last_pressed == obj) {
|
|
||||||
indev->proc.types.pointer.last_pressed = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(indev->group == group && obj == lv_indev_get_obj_act()) {
|
|
||||||
lv_indev_reset(indev, obj);
|
|
||||||
}
|
|
||||||
indev = lv_indev_get_next(indev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*All children deleted. Now clean up the object specific data*/
|
|
||||||
_lv_obj_destruct(obj);
|
|
||||||
|
|
||||||
/*Remove the screen for the screen list*/
|
|
||||||
if(obj->parent == NULL) {
|
|
||||||
lv_disp_t * disp = lv_obj_get_disp(obj);
|
|
||||||
uint32_t i;
|
|
||||||
/*Find the screen in the list*/
|
|
||||||
for(i = 0; i < disp->screen_cnt; i++) {
|
|
||||||
if(disp->screens[i] == obj) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t id = i;
|
|
||||||
for(i = id; i < disp->screen_cnt - 1; i++) {
|
|
||||||
disp->screens[i] = disp->screens[i + 1];
|
|
||||||
}
|
|
||||||
disp->screen_cnt--;
|
|
||||||
disp->screens = lv_mem_realloc(disp->screens, disp->screen_cnt * sizeof(lv_obj_t *));
|
|
||||||
}
|
|
||||||
/*Remove the object from the child list of its parent*/
|
|
||||||
else {
|
|
||||||
uint32_t id = lv_obj_get_index(obj);
|
|
||||||
uint32_t i;
|
|
||||||
for(i = id; i < obj->parent->spec_attr->child_cnt - 1; i++) {
|
|
||||||
obj->parent->spec_attr->children[i] = obj->parent->spec_attr->children[i + 1];
|
|
||||||
}
|
|
||||||
obj->parent->spec_attr->child_cnt--;
|
|
||||||
obj->parent->spec_attr->children = lv_mem_realloc(obj->parent->spec_attr->children,
|
|
||||||
obj->parent->spec_attr->child_cnt * sizeof(lv_obj_t *));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Free the object itself*/
|
|
||||||
lv_mem_free(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb, void * user_data)
|
|
||||||
{
|
|
||||||
lv_obj_tree_walk_res_t res = LV_OBJ_TREE_WALK_NEXT;
|
|
||||||
|
|
||||||
if(obj == NULL) {
|
|
||||||
lv_disp_t * disp = lv_disp_get_next(NULL);
|
|
||||||
while(disp) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < disp->screen_cnt; i++) {
|
|
||||||
walk_core(disp->screens[i], cb, user_data);
|
|
||||||
}
|
|
||||||
disp = lv_disp_get_next(disp);
|
|
||||||
}
|
|
||||||
return LV_OBJ_TREE_WALK_END; /*The value doesn't matter as it wasn't called recursively*/
|
|
||||||
}
|
|
||||||
|
|
||||||
res = cb(obj, user_data);
|
|
||||||
|
|
||||||
if(res == LV_OBJ_TREE_WALK_END) return LV_OBJ_TREE_WALK_END;
|
|
||||||
|
|
||||||
if(res != LV_OBJ_TREE_WALK_SKIP_CHILDREN) {
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
|
||||||
res = walk_core(lv_obj_get_child(obj, i), cb, user_data);
|
|
||||||
if(res == LV_OBJ_TREE_WALK_END) return LV_OBJ_TREE_WALK_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LV_OBJ_TREE_WALK_NEXT;
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file struct _lv_obj_tree.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_OBJ_TREE_H
|
|
||||||
#define LV_OBJ_TREE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_obj_t;
|
|
||||||
struct _lv_obj_class_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LV_OBJ_TREE_WALK_NEXT,
|
|
||||||
LV_OBJ_TREE_WALK_SKIP_CHILDREN,
|
|
||||||
LV_OBJ_TREE_WALK_END,
|
|
||||||
} lv_obj_tree_walk_res_t;
|
|
||||||
|
|
||||||
typedef lv_obj_tree_walk_res_t (*lv_obj_tree_walk_cb_t)(struct _lv_obj_t *, void *);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an object and all of its children.
|
|
||||||
* Also remove the objects from their group and remove all animations (if any).
|
|
||||||
* Send `LV_EVENT_DELETED` to deleted objects.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_del(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all children of an object.
|
|
||||||
* Also remove the objects from their group and remove all animations (if any).
|
|
||||||
* Send `LV_EVENT_DELETED` to deleted objects.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_obj_clean(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an object after some delay
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param delay_ms time to wait before delete in milliseconds
|
|
||||||
*/
|
|
||||||
void lv_obj_del_delayed(struct _lv_obj_t * obj, uint32_t delay_ms);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function to be easily used in animation ready callback to delete an object when the animation is ready
|
|
||||||
* @param a pointer to the animation
|
|
||||||
*/
|
|
||||||
void lv_obj_del_anim_ready_cb(lv_anim_t * a);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for asynchronously deleting objects.
|
|
||||||
* Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).
|
|
||||||
* @param obj object to delete
|
|
||||||
* @see lv_async_call
|
|
||||||
*/
|
|
||||||
void lv_obj_del_async(struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move the parent of an object. The relative coordinates will be kept.
|
|
||||||
*
|
|
||||||
* @param obj pointer to an object whose parent needs to be changed
|
|
||||||
* @param parent pointer to the new parent
|
|
||||||
*/
|
|
||||||
void lv_obj_set_parent(struct _lv_obj_t * obj, struct _lv_obj_t * parent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swap the positions of two objects.
|
|
||||||
* When used in listboxes, it can be used to sort the listbox items.
|
|
||||||
* @param obj1 pointer to the first object
|
|
||||||
* @param obj2 pointer to the second object
|
|
||||||
*/
|
|
||||||
void lv_obj_swap(struct _lv_obj_t * obj1, struct _lv_obj_t * obj2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* moves the object to the given index in its parent.
|
|
||||||
* When used in listboxes, it can be used to sort the listbox items.
|
|
||||||
* @param obj pointer to the object to be moved.
|
|
||||||
* @param index new index in parent. -1 to count from the back
|
|
||||||
* @note to move to the background: lv_obj_move_to_index(obj, 0)
|
|
||||||
* @note to move forward (up): lv_obj_move_to_index(obj, lv_obj_get_index(obj) - 1)
|
|
||||||
*/
|
|
||||||
void lv_obj_move_to_index(struct _lv_obj_t * obj, int32_t index);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the screen of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return pointer to the object's screen
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_obj_get_screen(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the display of the object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return pointer to the object's display
|
|
||||||
*/
|
|
||||||
lv_disp_t * lv_obj_get_disp(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the parent of an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the parent of the object. (NULL if `obj` was a screen)
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_obj_get_parent(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the child of an object by the child's index.
|
|
||||||
* @param obj pointer to an object whose child should be get
|
|
||||||
* @param id the index of the child.
|
|
||||||
* 0: the oldest (firstly created) child
|
|
||||||
* 1: the second oldest
|
|
||||||
* child count-1: the youngest
|
|
||||||
* -1: the youngest
|
|
||||||
* -2: the second youngest
|
|
||||||
* @return pointer to the child or NULL if the index was invalid
|
|
||||||
*/
|
|
||||||
struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of children
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the number of children
|
|
||||||
*/
|
|
||||||
uint32_t lv_obj_get_child_cnt(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the index of a child.
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the child index of the object.
|
|
||||||
* E.g. 0: the oldest (firstly created child)
|
|
||||||
*/
|
|
||||||
uint32_t lv_obj_get_index(const struct _lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate through all children of any object.
|
|
||||||
* @param start_obj start integrating from this object
|
|
||||||
* @param cb call this callback on the objects
|
|
||||||
* @param user_data pointer to any user related data (will be passed to `cb`)
|
|
||||||
*/
|
|
||||||
void lv_obj_tree_walk(struct _lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_OBJ_TREE_H*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,115 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_refr.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_REFR_H
|
|
||||||
#define LV_REFR_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_obj.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#define LV_REFR_TASK_PRIO LV_TASK_PRIO_MID
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the screen refresh subsystem
|
|
||||||
*/
|
|
||||||
void _lv_refr_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redraw the invalidated areas now.
|
|
||||||
* Normally the redrawing is periodically executed in `lv_timer_handler` but a long blocking process
|
|
||||||
* can prevent the call of `lv_timer_handler`. In this case if the GUI is updated in the process
|
|
||||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
|
||||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
|
||||||
*/
|
|
||||||
void lv_refr_now(lv_disp_t * disp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redrawn on object an all its children using the passed draw context
|
|
||||||
* @param draw pointer to an initialized draw context
|
|
||||||
* @param obj the start object from the redraw should start
|
|
||||||
*/
|
|
||||||
void lv_obj_redraw(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate an area on display to redraw it
|
|
||||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
|
||||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
|
||||||
* only one display)
|
|
||||||
*/
|
|
||||||
void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the display which is being refreshed
|
|
||||||
* @return the display being refreshed
|
|
||||||
*/
|
|
||||||
lv_disp_t * _lv_refr_get_disp_refreshing(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the display which is being refreshed.
|
|
||||||
* It shouldn't be used directly by the user.
|
|
||||||
* It can be used to trick the drawing functions about there is an active display.
|
|
||||||
* @param the display being refreshed
|
|
||||||
*/
|
|
||||||
void _lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
|
||||||
|
|
||||||
#if LV_USE_PERF_MONITOR
|
|
||||||
/**
|
|
||||||
* Reset FPS counter
|
|
||||||
*/
|
|
||||||
void lv_refr_reset_fps_counter(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the average FPS
|
|
||||||
* @return the average FPS
|
|
||||||
*/
|
|
||||||
uint32_t lv_refr_get_fps_avg(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called periodically to handle the refreshing
|
|
||||||
* @param timer pointer to the timer itself
|
|
||||||
*/
|
|
||||||
void _lv_disp_refr_timer(lv_timer_t * timer);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_REFR_H*/
|
|
@ -1,118 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_theme.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../../lvgl.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void apply_theme(lv_theme_t * th, lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
lv_theme_t * lv_theme_get_from_obj(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_disp_t * disp = obj ? lv_obj_get_disp(obj) : lv_disp_get_default();
|
|
||||||
return lv_disp_get_theme(disp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the active theme on an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @param name the name of the theme element to apply. E.g. `LV_THEME_BTN`
|
|
||||||
*/
|
|
||||||
void lv_theme_apply(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
if(th == NULL) return;
|
|
||||||
|
|
||||||
lv_obj_remove_style_all(obj);
|
|
||||||
|
|
||||||
apply_theme(th, obj); /*Apply the theme including the base theme(s)*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a base theme for a theme.
|
|
||||||
* The styles from the base them will be added before the styles of the current theme.
|
|
||||||
* Arbitrary long chain of themes can be created by setting base themes.
|
|
||||||
* @param new_theme pointer to theme which base should be set
|
|
||||||
* @param base pointer to the base theme
|
|
||||||
*/
|
|
||||||
void lv_theme_set_parent(lv_theme_t * new_theme, lv_theme_t * base)
|
|
||||||
{
|
|
||||||
new_theme->parent = base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a callback for a theme.
|
|
||||||
* The callback is used to add styles to different objects
|
|
||||||
* @param theme pointer to theme which callback should be set
|
|
||||||
* @param cb pointer to the callback
|
|
||||||
*/
|
|
||||||
void lv_theme_set_apply_cb(lv_theme_t * theme, lv_theme_apply_cb_t apply_cb)
|
|
||||||
{
|
|
||||||
theme->apply_cb = apply_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_font_t * lv_theme_get_font_small(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
return th ? th->font_small : LV_FONT_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_font_t * lv_theme_get_font_normal(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
return th ? th->font_normal : LV_FONT_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_font_t * lv_theme_get_font_large(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
return th ? th->font_large : LV_FONT_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_color_t lv_theme_get_color_primary(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
return th ? th->color_primary : lv_palette_main(LV_PALETTE_BLUE_GREY);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_color_t lv_theme_get_color_secondary(lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
lv_theme_t * th = lv_theme_get_from_obj(obj);
|
|
||||||
return th ? th->color_secondary : lv_palette_main(LV_PALETTE_BLUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void apply_theme(lv_theme_t * th, lv_obj_t * obj)
|
|
||||||
{
|
|
||||||
if(th->parent) apply_theme(th->parent, obj);
|
|
||||||
if(th->apply_cb) th->apply_cb(th, obj);
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
/**
|
|
||||||
*@file lv_theme.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_THEME_H
|
|
||||||
#define LV_THEME_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../core/lv_obj.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
struct _lv_theme_t;
|
|
||||||
struct _lv_disp_t;
|
|
||||||
|
|
||||||
typedef void (*lv_theme_apply_cb_t)(struct _lv_theme_t *, lv_obj_t *);
|
|
||||||
|
|
||||||
typedef struct _lv_theme_t {
|
|
||||||
lv_theme_apply_cb_t apply_cb;
|
|
||||||
struct _lv_theme_t * parent; /**< Apply the current theme's style on top of this theme.*/
|
|
||||||
void * user_data;
|
|
||||||
struct _lv_disp_t * disp;
|
|
||||||
lv_color_t color_primary;
|
|
||||||
lv_color_t color_secondary;
|
|
||||||
const lv_font_t * font_small;
|
|
||||||
const lv_font_t * font_normal;
|
|
||||||
const lv_font_t * font_large;
|
|
||||||
uint32_t flags; /*Any custom flag used by the theme*/
|
|
||||||
} lv_theme_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the theme assigned to the display of the object
|
|
||||||
* @param obj pointer to a theme object
|
|
||||||
* @return the theme of the object's display (can be NULL)
|
|
||||||
*/
|
|
||||||
lv_theme_t * lv_theme_get_from_obj(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the active theme on an object
|
|
||||||
* @param obj pointer to an object
|
|
||||||
*/
|
|
||||||
void lv_theme_apply(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a base theme for a theme.
|
|
||||||
* The styles from the base them will be added before the styles of the current theme.
|
|
||||||
* Arbitrary long chain of themes can be created by setting base themes.
|
|
||||||
* @param new_theme pointer to theme which base should be set
|
|
||||||
* @param parent pointer to the base theme
|
|
||||||
*/
|
|
||||||
void lv_theme_set_parent(lv_theme_t * new_theme, lv_theme_t * parent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an apply callback for a theme.
|
|
||||||
* The apply callback is used to add styles to different objects
|
|
||||||
* @param theme pointer to theme which callback should be set
|
|
||||||
* @param apply_cb pointer to the callback
|
|
||||||
*/
|
|
||||||
void lv_theme_set_apply_cb(lv_theme_t * theme, lv_theme_apply_cb_t apply_cb);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the small font of the theme
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return pointer to the font
|
|
||||||
*/
|
|
||||||
const lv_font_t * lv_theme_get_font_small(lv_obj_t * obj);
|
|
||||||
/**
|
|
||||||
* Get the normal font of the theme
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return pointer to the font
|
|
||||||
*/
|
|
||||||
const lv_font_t * lv_theme_get_font_normal(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the subtitle font of the theme
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return pointer to the font
|
|
||||||
*/
|
|
||||||
const lv_font_t * lv_theme_get_font_large(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the primary color of the theme
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the color
|
|
||||||
*/
|
|
||||||
lv_color_t lv_theme_get_color_primary(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the secondary color of the theme
|
|
||||||
* @param obj pointer to an object
|
|
||||||
* @return the color
|
|
||||||
*/
|
|
||||||
lv_color_t lv_theme_get_color_secondary(lv_obj_t * obj);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_THEME_H*/
|
|
@ -1,6 +0,0 @@
|
|||||||
CSRCS += lv_gpu_arm2d.c
|
|
||||||
|
|
||||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d
|
|
||||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d
|
|
||||||
|
|
||||||
CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d"
|
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_gpu_arm2d.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_GPU_ARM2D_H
|
|
||||||
#define LV_GPU_ARM2D_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../../misc/lv_color.h"
|
|
||||||
#include "../../hal/lv_hal_disp.h"
|
|
||||||
#include "../sw/lv_draw_sw.h"
|
|
||||||
|
|
||||||
#if LV_USE_GPU_ARM2D
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
typedef lv_draw_sw_ctx_t lv_draw_arm2d_ctx_t;
|
|
||||||
|
|
||||||
struct _lv_disp_drv_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_arm2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
|
||||||
|
|
||||||
void lv_draw_arm2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#endif /*LV_USE_GPU_ARM2D*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_GPU_ARM2D_H*/
|
|
@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_draw.h"
|
|
||||||
#include "sw/lv_draw_sw.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_init(void)
|
|
||||||
{
|
|
||||||
/*Nothing to init now*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_wait_for_finish(lv_draw_ctx_t * draw_ctx)
|
|
||||||
{
|
|
||||||
if(draw_ctx->wait_for_finish) draw_ctx->wait_for_finish(draw_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_DRAW_H
|
|
||||||
#define LV_DRAW_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../lv_conf_internal.h"
|
|
||||||
|
|
||||||
#include "../misc/lv_style.h"
|
|
||||||
#include "../misc/lv_txt.h"
|
|
||||||
#include "lv_img_decoder.h"
|
|
||||||
#include "lv_img_cache.h"
|
|
||||||
|
|
||||||
#include "lv_draw_rect.h"
|
|
||||||
#include "lv_draw_label.h"
|
|
||||||
#include "lv_draw_img.h"
|
|
||||||
#include "lv_draw_line.h"
|
|
||||||
#include "lv_draw_triangle.h"
|
|
||||||
#include "lv_draw_arc.h"
|
|
||||||
#include "lv_draw_mask.h"
|
|
||||||
#include "lv_draw_transform.h"
|
|
||||||
#include "lv_draw_layer.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void * user_data;
|
|
||||||
} lv_draw_mask_t;
|
|
||||||
|
|
||||||
typedef struct _lv_draw_layer_ctx_t {
|
|
||||||
lv_area_t area_full;
|
|
||||||
lv_area_t area_act;
|
|
||||||
lv_coord_t max_row_with_alpha;
|
|
||||||
lv_coord_t max_row_with_no_alpha;
|
|
||||||
void * buf;
|
|
||||||
struct {
|
|
||||||
const lv_area_t * clip_area;
|
|
||||||
lv_area_t * buf_area;
|
|
||||||
void * buf;
|
|
||||||
bool screen_transp;
|
|
||||||
} original;
|
|
||||||
} lv_draw_layer_ctx_t;
|
|
||||||
|
|
||||||
typedef struct _lv_draw_ctx_t {
|
|
||||||
/**
|
|
||||||
* Pointer to a buffer to draw into
|
|
||||||
*/
|
|
||||||
void * buf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The position and size of `buf` (absolute coordinates)
|
|
||||||
*/
|
|
||||||
lv_area_t * buf_area;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current clip area with absolute coordinates, always the same or smaller than `buf_area`
|
|
||||||
*/
|
|
||||||
const lv_area_t * clip_area;
|
|
||||||
|
|
||||||
|
|
||||||
void (*draw_rect)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
|
||||||
|
|
||||||
void (*draw_arc)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
|
||||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
|
||||||
|
|
||||||
void (*draw_img_decoded)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
|
||||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format);
|
|
||||||
|
|
||||||
lv_res_t (*draw_img)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * draw_dsc,
|
|
||||||
const lv_area_t * coords, const void * src);
|
|
||||||
|
|
||||||
void (*draw_letter)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
|
||||||
uint32_t letter);
|
|
||||||
|
|
||||||
|
|
||||||
void (*draw_line)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
|
|
||||||
const lv_point_t * point2);
|
|
||||||
|
|
||||||
|
|
||||||
void (*draw_polygon)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * draw_dsc,
|
|
||||||
const lv_point_t * points, uint16_t point_cnt);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an area of a transformed image (zoomed and/or rotated)
|
|
||||||
* @param draw_ctx pointer to a draw context
|
|
||||||
* @param dest_area get this area of the result image. It assumes that the original image is placed to the 0;0 position.
|
|
||||||
* @param src_buf the source image
|
|
||||||
* @param src_w width of the source image in [px]
|
|
||||||
* @param src_h height of the source image in [px]
|
|
||||||
* @param src_stride the stride in [px].
|
|
||||||
* @param draw_dsc an `lv_draw_img_dsc_t` descriptor containing the transformation parameters
|
|
||||||
* @param cf the color format of `src_buf`
|
|
||||||
* @param cbuf place the colors of the pixels on `dest_area` here in RGB format
|
|
||||||
* @param abuf place the opacity of the pixels on `dest_area` here
|
|
||||||
*/
|
|
||||||
void (*draw_transform)(struct _lv_draw_ctx_t * draw_ctx, const lv_area_t * dest_area, const void * src_buf,
|
|
||||||
lv_coord_t src_w, lv_coord_t src_h, lv_coord_t src_stride,
|
|
||||||
const lv_draw_img_dsc_t * draw_dsc, lv_img_cf_t cf, lv_color_t * cbuf, lv_opa_t * abuf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace the buffer with a rect without decoration like radius or borders
|
|
||||||
*/
|
|
||||||
void (*draw_bg)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * draw_dsc, const lv_area_t * coords);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait until all background operations are finished. (E.g. GPU operations)
|
|
||||||
*/
|
|
||||||
void (*wait_for_finish)(struct _lv_draw_ctx_t * draw_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy an area from buffer to an other
|
|
||||||
* @param draw_ctx pointer to a draw context
|
|
||||||
* @param dest_buf copy the buffer into this buffer
|
|
||||||
* @param dest_stride the width of the dest_buf in pixels
|
|
||||||
* @param dest_area the destination area
|
|
||||||
* @param src_buf copy from this buffer
|
|
||||||
* @param src_stride the width of src_buf in pixels
|
|
||||||
* @param src_area the source area.
|
|
||||||
*
|
|
||||||
* @note dest_area and src_area must have the same width and height
|
|
||||||
* but can have different x and y position.
|
|
||||||
* @note dest_area and src_area must be clipped to the real dimensions of the buffers
|
|
||||||
*/
|
|
||||||
void (*buffer_copy)(struct _lv_draw_ctx_t * draw_ctx, void * dest_buf, lv_coord_t dest_stride,
|
|
||||||
const lv_area_t * dest_area,
|
|
||||||
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a new layer context.
|
|
||||||
* The original buffer and area data are already saved from `draw_ctx` to `layer_ctx`
|
|
||||||
* @param draw_ctx pointer to the current draw context
|
|
||||||
* @param layer_area the coordinates of the layer
|
|
||||||
* @param flags OR-ed flags from @lv_draw_layer_flags_t
|
|
||||||
* @return pointer to the layer context, or NULL on error
|
|
||||||
*/
|
|
||||||
struct _lv_draw_layer_ctx_t * (*layer_init)(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
|
|
||||||
lv_draw_layer_flags_t flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjust the layer_ctx and/or draw_ctx based on the `layer_ctx->area_act`.
|
|
||||||
* It's called only if flags has `LV_DRAW_LAYER_FLAG_CAN_SUBDIVIDE`
|
|
||||||
* @param draw_ctx pointer to the current draw context
|
|
||||||
* @param layer_ctx pointer to a layer context
|
|
||||||
* @param flags OR-ed flags from @lv_draw_layer_flags_t
|
|
||||||
*/
|
|
||||||
void (*layer_adjust)(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
|
|
||||||
lv_draw_layer_flags_t flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blend a rendered layer to `layer_ctx->area_act`
|
|
||||||
* @param draw_ctx pointer to the current draw context
|
|
||||||
* @param layer_ctx pointer to a layer context
|
|
||||||
* @param draw_dsc pointer to an image draw descriptor
|
|
||||||
*/
|
|
||||||
void (*layer_blend)(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
|
|
||||||
const lv_draw_img_dsc_t * draw_dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy a layer context. The original buffer and area data of the `draw_ctx` will be restored
|
|
||||||
* and the `layer_ctx` itself will be freed automatically.
|
|
||||||
* @param draw_ctx pointer to the current draw context
|
|
||||||
* @param layer_ctx pointer to a layer context
|
|
||||||
*/
|
|
||||||
void (*layer_destroy)(struct _lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Size of a layer context in bytes.
|
|
||||||
*/
|
|
||||||
size_t layer_instance_size;
|
|
||||||
|
|
||||||
#if LV_USE_USER_DATA
|
|
||||||
void * user_data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} lv_draw_ctx_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
void lv_draw_wait_for_finish(lv_draw_ctx_t * draw_ctx);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* POST INCLUDES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_DRAW_H*/
|
|
@ -1,25 +0,0 @@
|
|||||||
CSRCS += lv_draw_arc.c
|
|
||||||
CSRCS += lv_draw.c
|
|
||||||
CSRCS += lv_draw_img.c
|
|
||||||
CSRCS += lv_draw_label.c
|
|
||||||
CSRCS += lv_draw_line.c
|
|
||||||
CSRCS += lv_draw_mask.c
|
|
||||||
CSRCS += lv_draw_rect.c
|
|
||||||
CSRCS += lv_draw_transform.c
|
|
||||||
CSRCS += lv_draw_layer.c
|
|
||||||
CSRCS += lv_draw_triangle.c
|
|
||||||
CSRCS += lv_img_buf.c
|
|
||||||
CSRCS += lv_img_cache.c
|
|
||||||
CSRCS += lv_img_decoder.c
|
|
||||||
|
|
||||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw
|
|
||||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw
|
|
||||||
|
|
||||||
CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw"
|
|
||||||
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d/lv_draw_arm2d.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/lv_draw_nxp.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl/lv_draw_sdl.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw/lv_draw_sw.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk
|
|
@ -1,152 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_arc.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_draw.h"
|
|
||||||
#include "lv_draw_arc.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
lv_memset_00(dsc, sizeof(lv_draw_arc_dsc_t));
|
|
||||||
dsc->width = 1;
|
|
||||||
dsc->opa = LV_OPA_COVER;
|
|
||||||
dsc->color = lv_color_black();
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, uint16_t radius,
|
|
||||||
uint16_t start_angle, uint16_t end_angle)
|
|
||||||
{
|
|
||||||
if(dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
if(dsc->width == 0) return;
|
|
||||||
if(start_angle == end_angle) return;
|
|
||||||
|
|
||||||
draw_ctx->draw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle);
|
|
||||||
|
|
||||||
// const lv_draw_backend_t * backend = lv_draw_backend_get();
|
|
||||||
// backend->draw_arc(center_x, center_y, radius, start_angle, end_angle, clip_area, dsc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_arc_get_area(lv_coord_t x, lv_coord_t y, uint16_t radius, uint16_t start_angle, uint16_t end_angle,
|
|
||||||
lv_coord_t w, bool rounded, lv_area_t * area)
|
|
||||||
{
|
|
||||||
lv_coord_t rout = radius;
|
|
||||||
|
|
||||||
/*Special case: full arc invalidation */
|
|
||||||
if(end_angle == start_angle + 360) {
|
|
||||||
area->x1 = x - rout;
|
|
||||||
area->y1 = y - rout;
|
|
||||||
area->x2 = x + rout;
|
|
||||||
area->y2 = y + rout;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(start_angle > 360) start_angle -= 360;
|
|
||||||
if(end_angle > 360) end_angle -= 360;
|
|
||||||
|
|
||||||
lv_coord_t rin = radius - w;
|
|
||||||
lv_coord_t extra_area = rounded ? w / 2 + 1 : 0;
|
|
||||||
uint8_t start_quarter = start_angle / 90;
|
|
||||||
uint8_t end_quarter = end_angle / 90;
|
|
||||||
|
|
||||||
/*360 deg still counts as quarter 3 (360 / 90 would be 4)*/
|
|
||||||
if(start_quarter == 4) start_quarter = 3;
|
|
||||||
if(end_quarter == 4) end_quarter = 3;
|
|
||||||
|
|
||||||
if(start_quarter == end_quarter && start_angle <= end_angle) {
|
|
||||||
if(start_quarter == 0) {
|
|
||||||
area->y1 = y + ((lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x2 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
|
|
||||||
area->y2 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->x1 = x + ((lv_trigo_sin(end_angle + 90) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 1) {
|
|
||||||
area->y2 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->x2 = x + ((lv_trigo_sin(start_angle + 90) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
|
|
||||||
area->y1 = y + ((lv_trigo_sin(end_angle) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x1 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 2) {
|
|
||||||
area->x1 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->y2 = y + ((lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
|
|
||||||
area->y1 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x2 = x + ((lv_trigo_sin(end_angle + 90) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 3) {
|
|
||||||
area->x1 = x + ((lv_trigo_sin(start_angle + 90) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->y1 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
|
|
||||||
area->x2 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->y2 = y + ((lv_trigo_sin(end_angle) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(start_quarter == 0 && end_quarter == 1) {
|
|
||||||
area->x1 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->y1 = y + ((LV_MIN(lv_trigo_sin(end_angle),
|
|
||||||
lv_trigo_sin(start_angle)) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x2 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->y2 = y + rout + extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 1 && end_quarter == 2) {
|
|
||||||
area->x1 = x - rout - extra_area;
|
|
||||||
area->y1 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x2 = x + ((LV_MAX(lv_trigo_sin(start_angle + 90),
|
|
||||||
lv_trigo_sin(end_angle + 90)) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->y2 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 2 && end_quarter == 3) {
|
|
||||||
area->x1 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->y1 = y - rout - extra_area;
|
|
||||||
area->x2 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
area->y2 = y + (LV_MAX(lv_trigo_sin(end_angle) * rin,
|
|
||||||
lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
}
|
|
||||||
else if(start_quarter == 3 && end_quarter == 0) {
|
|
||||||
area->x1 = x + ((LV_MIN(lv_trigo_sin(end_angle + 90),
|
|
||||||
lv_trigo_sin(start_angle + 90)) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->y1 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
|
||||||
area->x2 = x + rout + extra_area;
|
|
||||||
area->y2 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
area->x1 = x - rout;
|
|
||||||
area->y1 = y - rout;
|
|
||||||
area->x2 = x + rout;
|
|
||||||
area->y2 = y + rout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
@ -1,83 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_arc.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_DRAW_ARC_H
|
|
||||||
#define LV_DRAW_ARC_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../lv_conf_internal.h"
|
|
||||||
#include "../misc/lv_color.h"
|
|
||||||
#include "../misc/lv_area.h"
|
|
||||||
#include "../misc/lv_style.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
typedef struct {
|
|
||||||
lv_color_t color;
|
|
||||||
lv_coord_t width;
|
|
||||||
uint16_t start_angle;
|
|
||||||
uint16_t end_angle;
|
|
||||||
const void * img_src;
|
|
||||||
lv_opa_t opa;
|
|
||||||
lv_blend_mode_t blend_mode : 2;
|
|
||||||
uint8_t rounded : 1;
|
|
||||||
} lv_draw_arc_dsc_t;
|
|
||||||
|
|
||||||
struct _lv_draw_ctx_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw an arc. (Can draw pie too with great thickness.)
|
|
||||||
* @param center_x the x coordinate of the center of the arc
|
|
||||||
* @param center_y the y coordinate of the center of the arc
|
|
||||||
* @param radius the radius of the arc
|
|
||||||
* @param mask the arc will be drawn only in this mask
|
|
||||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
|
||||||
* @param end_angle the end angle of the arc
|
|
||||||
* @param clip_area the arc will be drawn only in this area
|
|
||||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
|
||||||
*/
|
|
||||||
void lv_draw_arc(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
|
||||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an area the should be invalidated when the arcs angle changed between start_angle and end_ange
|
|
||||||
* @param x the x coordinate of the center of the arc
|
|
||||||
* @param y the y coordinate of the center of the arc
|
|
||||||
* @param radius the radius of the arc
|
|
||||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
|
||||||
* @param end_angle the end angle of the arc
|
|
||||||
* @param w width of the arc
|
|
||||||
* @param rounded true: the arc is rounded
|
|
||||||
* @param area store the area to invalidate here
|
|
||||||
*/
|
|
||||||
void lv_draw_arc_get_area(lv_coord_t x, lv_coord_t y, uint16_t radius, uint16_t start_angle, uint16_t end_angle,
|
|
||||||
lv_coord_t w, bool rounded, lv_area_t * area);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_DRAW_ARC_H*/
|
|
@ -1,364 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_img.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_draw_img.h"
|
|
||||||
#include "lv_img_cache.h"
|
|
||||||
#include "../hal/lv_hal_disp.h"
|
|
||||||
#include "../misc/lv_log.h"
|
|
||||||
#include "../core/lv_refr.h"
|
|
||||||
#include "../misc/lv_mem.h"
|
|
||||||
#include "../misc/lv_math.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t decode_and_draw(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * draw_dsc,
|
|
||||||
const lv_area_t * coords, const void * src);
|
|
||||||
|
|
||||||
static void show_error(lv_draw_ctx_t * draw_ctx, const lv_area_t * coords, const char * msg);
|
|
||||||
static void draw_cleanup(_lv_img_cache_entry_t * cache);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
lv_memset_00(dsc, sizeof(lv_draw_img_dsc_t));
|
|
||||||
dsc->recolor = lv_color_black();
|
|
||||||
dsc->opa = LV_OPA_COVER;
|
|
||||||
dsc->zoom = LV_IMG_ZOOM_NONE;
|
|
||||||
dsc->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw an image
|
|
||||||
* @param coords the coordinates of the image
|
|
||||||
* @param mask the image will be drawn only in this area
|
|
||||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
|
||||||
* @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable
|
|
||||||
*/
|
|
||||||
void lv_draw_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, const lv_area_t * coords, const void * src)
|
|
||||||
{
|
|
||||||
if(src == NULL) {
|
|
||||||
LV_LOG_WARN("Image draw: src is NULL");
|
|
||||||
show_error(draw_ctx, coords, "No\ndata");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
lv_res_t res;
|
|
||||||
if(draw_ctx->draw_img) {
|
|
||||||
res = draw_ctx->draw_img(draw_ctx, dsc, coords, src);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = decode_and_draw(draw_ctx, dsc, coords, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res == LV_RES_INV) {
|
|
||||||
LV_LOG_WARN("Image draw error");
|
|
||||||
show_error(draw_ctx, coords, "No\ndata");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the pixel size of a color format in bits
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return the pixel size in bits
|
|
||||||
*/
|
|
||||||
uint8_t lv_img_cf_get_px_size(lv_img_cf_t cf)
|
|
||||||
{
|
|
||||||
uint8_t px_size = 0;
|
|
||||||
|
|
||||||
switch(cf) {
|
|
||||||
case LV_IMG_CF_UNKNOWN:
|
|
||||||
case LV_IMG_CF_RAW:
|
|
||||||
px_size = 0;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_TRUE_COLOR:
|
|
||||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
|
||||||
px_size = LV_COLOR_SIZE;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
|
||||||
px_size = LV_IMG_PX_SIZE_ALPHA_BYTE << 3;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_INDEXED_1BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_1BIT:
|
|
||||||
px_size = 1;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_INDEXED_2BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_2BIT:
|
|
||||||
px_size = 2;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_INDEXED_4BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_4BIT:
|
|
||||||
px_size = 4;
|
|
||||||
break;
|
|
||||||
case LV_IMG_CF_INDEXED_8BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_8BIT:
|
|
||||||
px_size = 8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
px_size = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return px_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color format is chroma keyed or not
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return true: chroma keyed; false: not chroma keyed
|
|
||||||
*/
|
|
||||||
bool lv_img_cf_is_chroma_keyed(lv_img_cf_t cf)
|
|
||||||
{
|
|
||||||
bool is_chroma_keyed = false;
|
|
||||||
|
|
||||||
switch(cf) {
|
|
||||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
|
||||||
case LV_IMG_CF_RAW_CHROMA_KEYED:
|
|
||||||
is_chroma_keyed = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
is_chroma_keyed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_chroma_keyed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color format has alpha channel or not
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return true: has alpha channel; false: doesn't have alpha channel
|
|
||||||
*/
|
|
||||||
bool lv_img_cf_has_alpha(lv_img_cf_t cf)
|
|
||||||
{
|
|
||||||
bool has_alpha = false;
|
|
||||||
|
|
||||||
switch(cf) {
|
|
||||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
|
||||||
case LV_IMG_CF_RAW_ALPHA:
|
|
||||||
case LV_IMG_CF_INDEXED_1BIT:
|
|
||||||
case LV_IMG_CF_INDEXED_2BIT:
|
|
||||||
case LV_IMG_CF_INDEXED_4BIT:
|
|
||||||
case LV_IMG_CF_INDEXED_8BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_1BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_2BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_4BIT:
|
|
||||||
case LV_IMG_CF_ALPHA_8BIT:
|
|
||||||
has_alpha = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
has_alpha = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the type of an image source
|
|
||||||
* @param src pointer to an image source:
|
|
||||||
* - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)
|
|
||||||
* - a path to a file (e.g. "S:/folder/image.bin")
|
|
||||||
* - or a symbol (e.g. LV_SYMBOL_CLOSE)
|
|
||||||
* @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN
|
|
||||||
*/
|
|
||||||
lv_img_src_t lv_img_src_get_type(const void * src)
|
|
||||||
{
|
|
||||||
lv_img_src_t img_src_type = LV_IMG_SRC_UNKNOWN;
|
|
||||||
|
|
||||||
if(src == NULL) return img_src_type;
|
|
||||||
const uint8_t * u8_p = src;
|
|
||||||
|
|
||||||
/*The first byte shows the type of the image source*/
|
|
||||||
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {
|
|
||||||
img_src_type = LV_IMG_SRC_FILE; /*If it's an ASCII character then it's file name*/
|
|
||||||
}
|
|
||||||
else if(u8_p[0] >= 0x80) {
|
|
||||||
img_src_type = LV_IMG_SRC_SYMBOL; /*Symbols begins after 0x7F*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
img_src_type = LV_IMG_SRC_VARIABLE; /*`lv_img_dsc_t` is draw to the first byte < 0x20*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if(LV_IMG_SRC_UNKNOWN == img_src_type) {
|
|
||||||
LV_LOG_WARN("lv_img_src_get_type: unknown image type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return img_src_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
|
||||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format)
|
|
||||||
{
|
|
||||||
if(draw_ctx->draw_img_decoded == NULL) return;
|
|
||||||
|
|
||||||
draw_ctx->draw_img_decoded(draw_ctx, dsc, coords, map_p, color_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
LV_ATTRIBUTE_FAST_MEM static lv_res_t decode_and_draw(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * draw_dsc,
|
|
||||||
const lv_area_t * coords, const void * src)
|
|
||||||
{
|
|
||||||
if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK;
|
|
||||||
|
|
||||||
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor, draw_dsc->frame_id);
|
|
||||||
|
|
||||||
if(cdsc == NULL) return LV_RES_INV;
|
|
||||||
|
|
||||||
lv_img_cf_t cf;
|
|
||||||
if(lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf)) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
|
|
||||||
else if(LV_IMG_CF_ALPHA_8BIT == cdsc->dec_dsc.header.cf) cf = LV_IMG_CF_ALPHA_8BIT;
|
|
||||||
else if(LV_IMG_CF_RGB565A8 == cdsc->dec_dsc.header.cf) cf = LV_IMG_CF_RGB565A8;
|
|
||||||
else if(lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf)) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
|
||||||
else cf = LV_IMG_CF_TRUE_COLOR;
|
|
||||||
|
|
||||||
if(cf == LV_IMG_CF_ALPHA_8BIT) {
|
|
||||||
if(draw_dsc->angle || draw_dsc->zoom != LV_IMG_ZOOM_NONE) {
|
|
||||||
/* resume normal method */
|
|
||||||
cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
|
||||||
cdsc->dec_dsc.img_data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
|
||||||
LV_LOG_WARN("Image draw error");
|
|
||||||
|
|
||||||
show_error(draw_ctx, coords, cdsc->dec_dsc.error_msg);
|
|
||||||
}
|
|
||||||
/*The decoder could open the image and gave the entire uncompressed image.
|
|
||||||
*Just draw it!*/
|
|
||||||
else if(cdsc->dec_dsc.img_data) {
|
|
||||||
lv_area_t map_area_rot;
|
|
||||||
lv_area_copy(&map_area_rot, coords);
|
|
||||||
if(draw_dsc->angle || draw_dsc->zoom != LV_IMG_ZOOM_NONE) {
|
|
||||||
int32_t w = lv_area_get_width(coords);
|
|
||||||
int32_t h = lv_area_get_height(coords);
|
|
||||||
|
|
||||||
_lv_img_buf_get_transformed_area(&map_area_rot, w, h, draw_dsc->angle, draw_dsc->zoom, &draw_dsc->pivot);
|
|
||||||
|
|
||||||
map_area_rot.x1 += coords->x1;
|
|
||||||
map_area_rot.y1 += coords->y1;
|
|
||||||
map_area_rot.x2 += coords->x1;
|
|
||||||
map_area_rot.y2 += coords->y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_area_t clip_com; /*Common area of mask and coords*/
|
|
||||||
bool union_ok;
|
|
||||||
union_ok = _lv_area_intersect(&clip_com, draw_ctx->clip_area, &map_area_rot);
|
|
||||||
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
|
|
||||||
if(union_ok == false) {
|
|
||||||
draw_cleanup(cdsc);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lv_area_t * clip_area_ori = draw_ctx->clip_area;
|
|
||||||
draw_ctx->clip_area = &clip_com;
|
|
||||||
lv_draw_img_decoded(draw_ctx, draw_dsc, coords, cdsc->dec_dsc.img_data, cf);
|
|
||||||
draw_ctx->clip_area = clip_area_ori;
|
|
||||||
}
|
|
||||||
/*The whole uncompressed image is not available. Try to read it line-by-line*/
|
|
||||||
else {
|
|
||||||
lv_area_t mask_com; /*Common area of mask and coords*/
|
|
||||||
bool union_ok;
|
|
||||||
union_ok = _lv_area_intersect(&mask_com, draw_ctx->clip_area, coords);
|
|
||||||
/*Out of mask. There is nothing to draw so the image is drawn successfully.*/
|
|
||||||
if(union_ok == false) {
|
|
||||||
draw_cleanup(cdsc);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t width = lv_area_get_width(&mask_com);
|
|
||||||
|
|
||||||
uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) *
|
|
||||||
LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
|
|
||||||
|
|
||||||
const lv_area_t * clip_area_ori = draw_ctx->clip_area;
|
|
||||||
lv_area_t line;
|
|
||||||
lv_area_copy(&line, &mask_com);
|
|
||||||
lv_area_set_height(&line, 1);
|
|
||||||
int32_t x = mask_com.x1 - coords->x1;
|
|
||||||
int32_t y = mask_com.y1 - coords->y1;
|
|
||||||
int32_t row;
|
|
||||||
lv_res_t read_res;
|
|
||||||
for(row = mask_com.y1; row <= mask_com.y2; row++) {
|
|
||||||
lv_area_t mask_line;
|
|
||||||
union_ok = _lv_area_intersect(&mask_line, clip_area_ori, &line);
|
|
||||||
if(union_ok == false) continue;
|
|
||||||
|
|
||||||
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
|
|
||||||
if(read_res != LV_RES_OK) {
|
|
||||||
lv_img_decoder_close(&cdsc->dec_dsc);
|
|
||||||
LV_LOG_WARN("Image draw can't read the line");
|
|
||||||
lv_mem_buf_release(buf);
|
|
||||||
draw_cleanup(cdsc);
|
|
||||||
draw_ctx->clip_area = clip_area_ori;
|
|
||||||
return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_ctx->clip_area = &mask_line;
|
|
||||||
lv_draw_img_decoded(draw_ctx, draw_dsc, &line, buf, cf);
|
|
||||||
line.y1++;
|
|
||||||
line.y2++;
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
draw_ctx->clip_area = clip_area_ori;
|
|
||||||
lv_mem_buf_release(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_cleanup(cdsc);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void show_error(lv_draw_ctx_t * draw_ctx, const lv_area_t * coords, const char * msg)
|
|
||||||
{
|
|
||||||
lv_draw_rect_dsc_t rect_dsc;
|
|
||||||
lv_draw_rect_dsc_init(&rect_dsc);
|
|
||||||
rect_dsc.bg_color = lv_color_white();
|
|
||||||
lv_draw_rect(draw_ctx, &rect_dsc, coords);
|
|
||||||
|
|
||||||
lv_draw_label_dsc_t label_dsc;
|
|
||||||
lv_draw_label_dsc_init(&label_dsc);
|
|
||||||
lv_draw_label(draw_ctx, &label_dsc, coords, msg, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_cleanup(_lv_img_cache_entry_t * cache)
|
|
||||||
{
|
|
||||||
/*Automatically close images with no caching*/
|
|
||||||
#if LV_IMG_CACHE_DEF_SIZE == 0
|
|
||||||
lv_img_decoder_close(&cache->dec_dsc);
|
|
||||||
#else
|
|
||||||
LV_UNUSED(cache);
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_img.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_DRAW_IMG_H
|
|
||||||
#define LV_DRAW_IMG_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_img_decoder.h"
|
|
||||||
#include "lv_img_buf.h"
|
|
||||||
#include "../misc/lv_style.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
int16_t angle;
|
|
||||||
uint16_t zoom;
|
|
||||||
lv_point_t pivot;
|
|
||||||
|
|
||||||
lv_color_t recolor;
|
|
||||||
lv_opa_t recolor_opa;
|
|
||||||
|
|
||||||
lv_opa_t opa;
|
|
||||||
lv_blend_mode_t blend_mode : 4;
|
|
||||||
|
|
||||||
int32_t frame_id;
|
|
||||||
uint8_t antialias : 1;
|
|
||||||
} lv_draw_img_dsc_t;
|
|
||||||
|
|
||||||
struct _lv_draw_ctx_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc);
|
|
||||||
/**
|
|
||||||
* Draw an image
|
|
||||||
* @param coords the coordinates of the image
|
|
||||||
* @param mask the image will be drawn only in this area
|
|
||||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
|
||||||
* @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable
|
|
||||||
*/
|
|
||||||
void lv_draw_img(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, const lv_area_t * coords,
|
|
||||||
const void * src);
|
|
||||||
|
|
||||||
|
|
||||||
void lv_draw_img_decoded(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
|
||||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the type of an image source
|
|
||||||
* @param src pointer to an image source:
|
|
||||||
* - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)
|
|
||||||
* - a path to a file (e.g. "S:/folder/image.bin")
|
|
||||||
* - or a symbol (e.g. LV_SYMBOL_CLOSE)
|
|
||||||
* @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN
|
|
||||||
*/
|
|
||||||
lv_img_src_t lv_img_src_get_type(const void * src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the pixel size of a color format in bits
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return the pixel size in bits
|
|
||||||
*/
|
|
||||||
uint8_t lv_img_cf_get_px_size(lv_img_cf_t cf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color format is chroma keyed or not
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return true: chroma keyed; false: not chroma keyed
|
|
||||||
*/
|
|
||||||
bool lv_img_cf_is_chroma_keyed(lv_img_cf_t cf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color format has alpha channel or not
|
|
||||||
* @param cf a color format (`LV_IMG_CF_...`)
|
|
||||||
* @return true: has alpha channel; false: doesn't have alpha channel
|
|
||||||
*/
|
|
||||||
bool lv_img_cf_has_alpha(lv_img_cf_t cf);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_DRAW_IMG_H*/
|
|
@ -1,417 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_label.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_draw.h"
|
|
||||||
#include "lv_draw_label.h"
|
|
||||||
#include "../misc/lv_math.h"
|
|
||||||
#include "../hal/lv_hal_disp.h"
|
|
||||||
#include "../core/lv_refr.h"
|
|
||||||
#include "../misc/lv_bidi.h"
|
|
||||||
#include "../misc/lv_assert.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define LABEL_RECOLOR_PAR_LENGTH 6
|
|
||||||
#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
enum {
|
|
||||||
CMD_STATE_WAIT,
|
|
||||||
CMD_STATE_PAR,
|
|
||||||
CMD_STATE_IN,
|
|
||||||
};
|
|
||||||
typedef uint8_t cmd_state_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static uint8_t hex_char_to_num(char hex);
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
lv_memset_00(dsc, sizeof(lv_draw_label_dsc_t));
|
|
||||||
dsc->opa = LV_OPA_COVER;
|
|
||||||
dsc->color = lv_color_black();
|
|
||||||
dsc->font = LV_FONT_DEFAULT;
|
|
||||||
dsc->sel_start = LV_DRAW_LABEL_NO_TXT_SEL;
|
|
||||||
dsc->sel_end = LV_DRAW_LABEL_NO_TXT_SEL;
|
|
||||||
dsc->sel_color = lv_color_black();
|
|
||||||
dsc->sel_bg_color = lv_palette_main(LV_PALETTE_BLUE);
|
|
||||||
dsc->bidi_dir = LV_BASE_DIR_LTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a text
|
|
||||||
* @param coords coordinates of the label
|
|
||||||
* @param mask the label will be drawn only in this area
|
|
||||||
* @param dsc pointer to draw descriptor
|
|
||||||
* @param txt `\0` terminated text to write
|
|
||||||
* @param hint pointer to a `lv_draw_label_hint_t` variable.
|
|
||||||
* It is managed by the draw to speed up the drawing of very long texts (thousands of lines).
|
|
||||||
*/
|
|
||||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc,
|
|
||||||
const lv_area_t * coords, const char * txt, lv_draw_label_hint_t * hint)
|
|
||||||
{
|
|
||||||
if(dsc->opa <= LV_OPA_MIN) return;
|
|
||||||
if(dsc->font == NULL) {
|
|
||||||
LV_LOG_WARN("dsc->font == NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(draw_ctx->draw_letter == NULL) {
|
|
||||||
LV_LOG_WARN("draw->draw_letter == NULL (there is no function to draw letters)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_draw_label_dsc_t dsc_mod = *dsc;
|
|
||||||
|
|
||||||
const lv_font_t * font = dsc->font;
|
|
||||||
int32_t w;
|
|
||||||
|
|
||||||
/*No need to waste processor time if string is empty*/
|
|
||||||
if(txt == NULL || txt[0] == '\0')
|
|
||||||
return;
|
|
||||||
|
|
||||||
lv_area_t clipped_area;
|
|
||||||
bool clip_ok = _lv_area_intersect(&clipped_area, coords, draw_ctx->clip_area);
|
|
||||||
if(!clip_ok) return;
|
|
||||||
|
|
||||||
lv_text_align_t align = dsc->align;
|
|
||||||
lv_base_dir_t base_dir = dsc->bidi_dir;
|
|
||||||
|
|
||||||
lv_bidi_calculate_align(&align, &base_dir, txt);
|
|
||||||
|
|
||||||
if((dsc->flag & LV_TEXT_FLAG_EXPAND) == 0) {
|
|
||||||
/*Normally use the label's width as width*/
|
|
||||||
w = lv_area_get_width(coords);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*If EXPAND is enabled then not limit the text's width to the object's width*/
|
|
||||||
lv_point_t p;
|
|
||||||
lv_txt_get_size(&p, txt, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX,
|
|
||||||
dsc->flag);
|
|
||||||
w = p.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t line_height_font = lv_font_get_line_height(font);
|
|
||||||
int32_t line_height = line_height_font + dsc->line_space;
|
|
||||||
|
|
||||||
/*Init variables for the first line*/
|
|
||||||
int32_t line_width = 0;
|
|
||||||
lv_point_t pos;
|
|
||||||
pos.x = coords->x1;
|
|
||||||
pos.y = coords->y1;
|
|
||||||
|
|
||||||
int32_t x_ofs = 0;
|
|
||||||
int32_t y_ofs = 0;
|
|
||||||
x_ofs = dsc->ofs_x;
|
|
||||||
y_ofs = dsc->ofs_y;
|
|
||||||
pos.y += y_ofs;
|
|
||||||
|
|
||||||
uint32_t line_start = 0;
|
|
||||||
int32_t last_line_start = -1;
|
|
||||||
|
|
||||||
/*Check the hint to use the cached info*/
|
|
||||||
if(hint && y_ofs == 0 && coords->y1 < 0) {
|
|
||||||
/*If the label changed too much recalculate the hint.*/
|
|
||||||
if(LV_ABS(hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) {
|
|
||||||
hint->line_start = -1;
|
|
||||||
}
|
|
||||||
last_line_start = hint->line_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Use the hint if it's valid*/
|
|
||||||
if(hint && last_line_start >= 0) {
|
|
||||||
line_start = last_line_start;
|
|
||||||
pos.y += hint->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t line_end = line_start + _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, NULL, dsc->flag);
|
|
||||||
|
|
||||||
/*Go the first visible line*/
|
|
||||||
while(pos.y + line_height_font < draw_ctx->clip_area->y1) {
|
|
||||||
/*Go to next line*/
|
|
||||||
line_start = line_end;
|
|
||||||
line_end += _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, NULL, dsc->flag);
|
|
||||||
pos.y += line_height;
|
|
||||||
|
|
||||||
/*Save at the threshold coordinate*/
|
|
||||||
if(hint && pos.y >= -LV_LABEL_HINT_UPDATE_TH && hint->line_start < 0) {
|
|
||||||
hint->line_start = line_start;
|
|
||||||
hint->y = pos.y - coords->y1;
|
|
||||||
hint->coord_y = coords->y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(txt[line_start] == '\0') return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Align to middle*/
|
|
||||||
if(align == LV_TEXT_ALIGN_CENTER) {
|
|
||||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
|
||||||
|
|
||||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
|
||||||
|
|
||||||
}
|
|
||||||
/*Align to the right*/
|
|
||||||
else if(align == LV_TEXT_ALIGN_RIGHT) {
|
|
||||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
|
||||||
pos.x += lv_area_get_width(coords) - line_width;
|
|
||||||
}
|
|
||||||
uint32_t sel_start = dsc->sel_start;
|
|
||||||
uint32_t sel_end = dsc->sel_end;
|
|
||||||
if(sel_start > sel_end) {
|
|
||||||
uint32_t tmp = sel_start;
|
|
||||||
sel_start = sel_end;
|
|
||||||
sel_end = tmp;
|
|
||||||
}
|
|
||||||
lv_draw_line_dsc_t line_dsc;
|
|
||||||
|
|
||||||
if((dsc->decor & LV_TEXT_DECOR_UNDERLINE) || (dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH)) {
|
|
||||||
lv_draw_line_dsc_init(&line_dsc);
|
|
||||||
line_dsc.color = dsc->color;
|
|
||||||
line_dsc.width = font->underline_thickness ? font->underline_thickness : 1;
|
|
||||||
line_dsc.opa = dsc->opa;
|
|
||||||
line_dsc.blend_mode = dsc->blend_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t par_start = 0;
|
|
||||||
lv_color_t recolor = lv_color_black();
|
|
||||||
lv_color_t color = lv_color_black();
|
|
||||||
int32_t letter_w;
|
|
||||||
|
|
||||||
lv_draw_rect_dsc_t draw_dsc_sel;
|
|
||||||
lv_draw_rect_dsc_init(&draw_dsc_sel);
|
|
||||||
draw_dsc_sel.bg_color = dsc->sel_bg_color;
|
|
||||||
|
|
||||||
int32_t pos_x_start = pos.x;
|
|
||||||
/*Write out all lines*/
|
|
||||||
while(txt[line_start] != '\0') {
|
|
||||||
pos.x += x_ofs;
|
|
||||||
|
|
||||||
/*Write all letter of a line*/
|
|
||||||
cmd_state = CMD_STATE_WAIT;
|
|
||||||
i = 0;
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
char * bidi_txt = lv_mem_buf_get(line_end - line_start + 1);
|
|
||||||
_lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, base_dir, NULL, 0);
|
|
||||||
#else
|
|
||||||
const char * bidi_txt = txt + line_start;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while(i < line_end - line_start) {
|
|
||||||
uint32_t logical_char_pos = 0;
|
|
||||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
logical_char_pos = _lv_txt_encoded_get_char_id(txt, line_start);
|
|
||||||
uint32_t t = _lv_txt_encoded_get_char_id(bidi_txt, i);
|
|
||||||
logical_char_pos += _lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, t, NULL);
|
|
||||||
#else
|
|
||||||
logical_char_pos = _lv_txt_encoded_get_char_id(txt, line_start + i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t letter;
|
|
||||||
uint32_t letter_next;
|
|
||||||
_lv_txt_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i);
|
|
||||||
/*Handle the re-color command*/
|
|
||||||
if((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) {
|
|
||||||
if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) {
|
|
||||||
if(cmd_state == CMD_STATE_WAIT) { /*Start char*/
|
|
||||||
par_start = i;
|
|
||||||
cmd_state = CMD_STATE_PAR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(cmd_state == CMD_STATE_PAR) { /*Other start char in parameter escaped cmd. char*/
|
|
||||||
cmd_state = CMD_STATE_WAIT;
|
|
||||||
}
|
|
||||||
else if(cmd_state == CMD_STATE_IN) { /*Command end*/
|
|
||||||
cmd_state = CMD_STATE_WAIT;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Skip the color parameter and wait the space after it*/
|
|
||||||
if(cmd_state == CMD_STATE_PAR) {
|
|
||||||
if(letter == ' ') {
|
|
||||||
/*Get the parameter*/
|
|
||||||
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
|
||||||
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
|
||||||
lv_memcpy_small(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
|
||||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
|
||||||
int r, g, b;
|
|
||||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
|
||||||
g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]);
|
|
||||||
b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]);
|
|
||||||
recolor = lv_color_make(r, g, b);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
recolor.full = dsc->color.full;
|
|
||||||
}
|
|
||||||
cmd_state = CMD_STATE_IN; /*After the parameter the text is in the command*/
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
color = dsc->color;
|
|
||||||
|
|
||||||
if(cmd_state == CMD_STATE_IN) color = recolor;
|
|
||||||
|
|
||||||
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
|
||||||
|
|
||||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
|
||||||
if(logical_char_pos >= sel_start && logical_char_pos < sel_end) {
|
|
||||||
lv_area_t sel_coords;
|
|
||||||
sel_coords.x1 = pos.x;
|
|
||||||
sel_coords.y1 = pos.y;
|
|
||||||
sel_coords.x2 = pos.x + letter_w + dsc->letter_space - 1;
|
|
||||||
sel_coords.y2 = pos.y + line_height - 1;
|
|
||||||
lv_draw_rect(draw_ctx, &draw_dsc_sel, &sel_coords);
|
|
||||||
color = dsc->sel_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dsc_mod.color = color;
|
|
||||||
lv_draw_letter(draw_ctx, &dsc_mod, &pos, letter);
|
|
||||||
|
|
||||||
if(letter_w > 0) {
|
|
||||||
pos.x += letter_w + dsc->letter_space;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH) {
|
|
||||||
lv_point_t p1;
|
|
||||||
lv_point_t p2;
|
|
||||||
p1.x = pos_x_start;
|
|
||||||
p1.y = pos.y + (dsc->font->line_height / 2) + line_dsc.width / 2;
|
|
||||||
p2.x = pos.x;
|
|
||||||
p2.y = p1.y;
|
|
||||||
line_dsc.color = color;
|
|
||||||
lv_draw_line(draw_ctx, &line_dsc, &p1, &p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dsc->decor & LV_TEXT_DECOR_UNDERLINE) {
|
|
||||||
lv_point_t p1;
|
|
||||||
lv_point_t p2;
|
|
||||||
p1.x = pos_x_start;
|
|
||||||
p1.y = pos.y + dsc->font->line_height - dsc->font->base_line - font->underline_position;
|
|
||||||
p2.x = pos.x;
|
|
||||||
p2.y = p1.y;
|
|
||||||
line_dsc.color = color;
|
|
||||||
lv_draw_line(draw_ctx, &line_dsc, &p1, &p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LV_USE_BIDI
|
|
||||||
lv_mem_buf_release(bidi_txt);
|
|
||||||
bidi_txt = NULL;
|
|
||||||
#endif
|
|
||||||
/*Go to next line*/
|
|
||||||
line_start = line_end;
|
|
||||||
line_end += _lv_txt_get_next_line(&txt[line_start], font, dsc->letter_space, w, NULL, dsc->flag);
|
|
||||||
|
|
||||||
pos.x = coords->x1;
|
|
||||||
/*Align to middle*/
|
|
||||||
if(align == LV_TEXT_ALIGN_CENTER) {
|
|
||||||
line_width =
|
|
||||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
|
||||||
|
|
||||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
|
||||||
|
|
||||||
}
|
|
||||||
/*Align to the right*/
|
|
||||||
else if(align == LV_TEXT_ALIGN_RIGHT) {
|
|
||||||
line_width =
|
|
||||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag);
|
|
||||||
pos.x += lv_area_get_width(coords) - line_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Go the next line position*/
|
|
||||||
pos.y += line_height;
|
|
||||||
|
|
||||||
if(pos.y > draw_ctx->clip_area->y2) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LV_ASSERT_MEM_INTEGRITY();
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
|
||||||
uint32_t letter)
|
|
||||||
{
|
|
||||||
draw_ctx->draw_letter(draw_ctx, dsc, pos_p, letter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a hexadecimal characters to a number (0..15)
|
|
||||||
* @param hex Pointer to a hexadecimal character (0..9, A..F)
|
|
||||||
* @return the numerical value of `hex` or 0 on error
|
|
||||||
*/
|
|
||||||
static uint8_t hex_char_to_num(char hex)
|
|
||||||
{
|
|
||||||
uint8_t result = 0;
|
|
||||||
|
|
||||||
if(hex >= '0' && hex <= '9') {
|
|
||||||
result = hex - '0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
|
||||||
|
|
||||||
switch(hex) {
|
|
||||||
case 'A':
|
|
||||||
result = 10;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
result = 11;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
result = 12;
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
result = 13;
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
result = 14;
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
result = 15;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_label.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV_DRAW_LABEL_H
|
|
||||||
#define LV_DRAW_LABEL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "../misc/lv_bidi.h"
|
|
||||||
#include "../misc/lv_txt.h"
|
|
||||||
#include "../misc/lv_color.h"
|
|
||||||
#include "../misc/lv_style.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF)
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const lv_font_t * font;
|
|
||||||
uint32_t sel_start;
|
|
||||||
uint32_t sel_end;
|
|
||||||
lv_color_t color;
|
|
||||||
lv_color_t sel_color;
|
|
||||||
lv_color_t sel_bg_color;
|
|
||||||
lv_coord_t line_space;
|
|
||||||
lv_coord_t letter_space;
|
|
||||||
lv_coord_t ofs_x;
|
|
||||||
lv_coord_t ofs_y;
|
|
||||||
lv_opa_t opa;
|
|
||||||
lv_base_dir_t bidi_dir;
|
|
||||||
lv_text_align_t align;
|
|
||||||
lv_text_flag_t flag;
|
|
||||||
lv_text_decor_t decor : 3;
|
|
||||||
lv_blend_mode_t blend_mode: 3;
|
|
||||||
} lv_draw_label_dsc_t;
|
|
||||||
|
|
||||||
/** Store some info to speed up drawing of very large texts
|
|
||||||
* It takes a lot of time to get the first visible character because
|
|
||||||
* all the previous characters needs to be checked to calculate the positions.
|
|
||||||
* This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line.
|
|
||||||
* Therefore the calculations can start from here.*/
|
|
||||||
typedef struct _lv_draw_label_hint_t {
|
|
||||||
/** Index of the line at `y` coordinate*/
|
|
||||||
int32_t line_start;
|
|
||||||
|
|
||||||
/** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/
|
|
||||||
int32_t y;
|
|
||||||
|
|
||||||
/** The 'y1' coordinate of the label when the hint was saved.
|
|
||||||
* Used to invalidate the hint if the label has moved too much.*/
|
|
||||||
int32_t coord_y;
|
|
||||||
} lv_draw_label_hint_t;
|
|
||||||
|
|
||||||
struct _lv_draw_ctx_t;
|
|
||||||
/**********************
|
|
||||||
* GLOBAL PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a text
|
|
||||||
* @param coords coordinates of the label
|
|
||||||
* @param mask the label will be drawn only in this area
|
|
||||||
* @param dsc pointer to draw descriptor
|
|
||||||
* @param txt `\0` terminated text to write
|
|
||||||
* @param hint pointer to a `lv_draw_label_hint_t` variable.
|
|
||||||
* It is managed by the draw to speed up the drawing of very long texts (thousands of lines).
|
|
||||||
*/
|
|
||||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc,
|
|
||||||
const lv_area_t * coords, const char * txt, lv_draw_label_hint_t * hint);
|
|
||||||
|
|
||||||
void lv_draw_letter(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
|
||||||
uint32_t letter);
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
* GLOBAL VARIABLES
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /*extern "C"*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*LV_DRAW_LABEL_H*/
|
|
@ -1,93 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_layer.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
#include "lv_draw.h"
|
|
||||||
#include "lv_draw_arc.h"
|
|
||||||
#include "../core/lv_refr.h"
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
lv_draw_layer_ctx_t * lv_draw_layer_create(lv_draw_ctx_t * draw_ctx, const lv_area_t * layer_area,
|
|
||||||
lv_draw_layer_flags_t flags)
|
|
||||||
{
|
|
||||||
if(draw_ctx->layer_init == NULL) return NULL;
|
|
||||||
|
|
||||||
lv_draw_layer_ctx_t * layer_ctx = lv_mem_alloc(draw_ctx->layer_instance_size);
|
|
||||||
LV_ASSERT_MALLOC(layer_ctx);
|
|
||||||
if(layer_ctx == NULL) {
|
|
||||||
LV_LOG_WARN("Couldn't allocate a new layer context");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_memset_00(layer_ctx, draw_ctx->layer_instance_size);
|
|
||||||
|
|
||||||
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
|
|
||||||
layer_ctx->original.buf = draw_ctx->buf;
|
|
||||||
layer_ctx->original.buf_area = draw_ctx->buf_area;
|
|
||||||
layer_ctx->original.clip_area = draw_ctx->clip_area;
|
|
||||||
layer_ctx->original.screen_transp = disp_refr->driver->screen_transp;
|
|
||||||
layer_ctx->area_full = *layer_area;
|
|
||||||
|
|
||||||
lv_draw_layer_ctx_t * init_layer_ctx = draw_ctx->layer_init(draw_ctx, layer_ctx, flags);
|
|
||||||
if(NULL == init_layer_ctx) {
|
|
||||||
lv_mem_free(layer_ctx);
|
|
||||||
}
|
|
||||||
return init_layer_ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
|
|
||||||
lv_draw_layer_flags_t flags)
|
|
||||||
{
|
|
||||||
if(draw_ctx->layer_adjust) draw_ctx->layer_adjust(draw_ctx, layer_ctx, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_layer_blend(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
|
|
||||||
lv_draw_img_dsc_t * draw_dsc)
|
|
||||||
{
|
|
||||||
if(draw_ctx->layer_blend) draw_ctx->layer_blend(draw_ctx, layer_ctx, draw_dsc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_draw_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
|
|
||||||
{
|
|
||||||
|
|
||||||
lv_draw_wait_for_finish(draw_ctx);
|
|
||||||
draw_ctx->buf = layer_ctx->original.buf;
|
|
||||||
draw_ctx->buf_area = layer_ctx->original.buf_area;
|
|
||||||
draw_ctx->clip_area = layer_ctx->original.clip_area;
|
|
||||||
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
|
|
||||||
disp_refr->driver->screen_transp = layer_ctx->original.screen_transp;
|
|
||||||
|
|
||||||
if(draw_ctx->layer_destroy) draw_ctx->layer_destroy(draw_ctx, layer_ctx);
|
|
||||||
lv_mem_free(layer_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user