mirror of
https://github.com/Valeh2012/PersonalVotingMachine
synced 2025-12-07 09:35:13 +02:00
first commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
This is the 4-wire resistive touch screen firmware for Arduino. Works with all Arduinos and Teensy
|
||||
|
||||
|
||||
To install, click DOWNLOAD SOURCE in the top right corner, and rename the uncompressed folder "TouchScreen". See our tutorial at http://www.ladyada.net/library/arduino/libraries.html on Arduino Library installation
|
||||
260
extended-setup/components/Adafruit_TouchScreen/TouchScreen.cpp
Normal file
260
extended-setup/components/Adafruit_TouchScreen/TouchScreen.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
// Touch screen library with X Y and Z (pressure) readings as well
|
||||
// as oversampling to avoid 'bouncing'
|
||||
// (c) ladyada / adafruit
|
||||
// Code under MIT License
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#ifdef __AVR
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#endif
|
||||
#include "TouchScreen.h"
|
||||
|
||||
// increase or decrease the touchscreen oversampling. This is a little different than you make think:
|
||||
// 1 is no oversampling, whatever data we get is immediately returned
|
||||
// 2 is double-sampling and we only return valid data if both points are the same
|
||||
// 3+ uses insert sort to get the median value.
|
||||
// We found 2 is precise yet not too slow so we suggest sticking with it!
|
||||
|
||||
#define NUMSAMPLES 2
|
||||
|
||||
TSPoint::TSPoint(void) {
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) {
|
||||
x = x0;
|
||||
y = y0;
|
||||
z = z0;
|
||||
}
|
||||
|
||||
bool TSPoint::operator==(TSPoint p1) {
|
||||
return ((p1.x == x) && (p1.y == y) && (p1.z == z));
|
||||
}
|
||||
|
||||
bool TSPoint::operator!=(TSPoint p1) {
|
||||
return ((p1.x != x) || (p1.y != y) || (p1.z != z));
|
||||
}
|
||||
|
||||
#if (NUMSAMPLES > 2)
|
||||
static void insert_sort(int array[], uint8_t size) {
|
||||
uint8_t j;
|
||||
int save;
|
||||
|
||||
for (int i = 1; i < size; i++) {
|
||||
save = array[i];
|
||||
for (j = i; j >= 1 && save < array[j - 1]; j--)
|
||||
array[j] = array[j - 1];
|
||||
array[j] = save;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TSPoint TouchScreen::getPoint(void) {
|
||||
int x, y, z;
|
||||
int samples[NUMSAMPLES];
|
||||
uint8_t i, valid;
|
||||
|
||||
valid = 1;
|
||||
|
||||
pinMode(_yp, INPUT);
|
||||
pinMode(_ym, INPUT);
|
||||
pinMode(_xp, OUTPUT);
|
||||
pinMode(_xm, OUTPUT);
|
||||
|
||||
#if defined (USE_FAST_PINIO)
|
||||
*xp_port |= xp_pin;
|
||||
*xm_port &= ~xm_pin;
|
||||
#else
|
||||
digitalWrite(_xp, HIGH);
|
||||
digitalWrite(_xm, LOW);
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
delayMicroseconds(20); // Fast ARM chips need to allow voltages to settle
|
||||
#endif
|
||||
|
||||
for (i=0; i<NUMSAMPLES; i++) {
|
||||
samples[i] = analogRead(_yp);
|
||||
}
|
||||
|
||||
#if NUMSAMPLES > 2
|
||||
insert_sort(samples, NUMSAMPLES);
|
||||
#endif
|
||||
#if NUMSAMPLES == 2
|
||||
// Allow small amount of measurement noise, because capacitive
|
||||
// coupling to a TFT display's signals can induce some noise.
|
||||
if (samples[0] - samples[1] < -4 || samples[0] - samples[1] > 4) {
|
||||
valid = 0;
|
||||
} else {
|
||||
samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples
|
||||
}
|
||||
#endif
|
||||
|
||||
x = (1023-samples[NUMSAMPLES/2]);
|
||||
|
||||
pinMode(_xp, INPUT);
|
||||
pinMode(_xm, INPUT);
|
||||
pinMode(_yp, OUTPUT);
|
||||
pinMode(_ym, OUTPUT);
|
||||
|
||||
#if defined (USE_FAST_PINIO)
|
||||
*ym_port &= ~ym_pin;
|
||||
*yp_port |= yp_pin;
|
||||
#else
|
||||
digitalWrite(_ym, LOW);
|
||||
digitalWrite(_yp, HIGH);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __arm__
|
||||
delayMicroseconds(20); // Fast ARM chips need to allow voltages to settle
|
||||
#endif
|
||||
|
||||
for (i=0; i<NUMSAMPLES; i++) {
|
||||
samples[i] = analogRead(_xm);
|
||||
}
|
||||
|
||||
#if NUMSAMPLES > 2
|
||||
insert_sort(samples, NUMSAMPLES);
|
||||
#endif
|
||||
#if NUMSAMPLES == 2
|
||||
// Allow small amount of measurement noise, because capacitive
|
||||
// coupling to a TFT display's signals can induce some noise.
|
||||
if (samples[0] - samples[1] < -4 || samples[0] - samples[1] > 4) {
|
||||
valid = 0;
|
||||
} else {
|
||||
samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples
|
||||
}
|
||||
#endif
|
||||
|
||||
y = (1023-samples[NUMSAMPLES/2]);
|
||||
|
||||
// Set X+ to ground
|
||||
// Set Y- to VCC
|
||||
// Hi-Z X- and Y+
|
||||
pinMode(_xp, OUTPUT);
|
||||
pinMode(_yp, INPUT);
|
||||
|
||||
#if defined (USE_FAST_PINIO)
|
||||
*xp_port &= ~xp_pin;
|
||||
*ym_port |= ym_pin;
|
||||
#else
|
||||
digitalWrite(_xp, LOW);
|
||||
digitalWrite(_ym, HIGH);
|
||||
#endif
|
||||
|
||||
int z1 = analogRead(_xm);
|
||||
int z2 = analogRead(_yp);
|
||||
|
||||
if (_rxplate != 0) {
|
||||
// now read the x
|
||||
float rtouch;
|
||||
rtouch = z2;
|
||||
rtouch /= z1;
|
||||
rtouch -= 1;
|
||||
rtouch *= x;
|
||||
rtouch *= _rxplate;
|
||||
rtouch /= 1024;
|
||||
|
||||
z = rtouch;
|
||||
} else {
|
||||
z = (1023-(z2-z1));
|
||||
}
|
||||
|
||||
if (! valid) {
|
||||
z = 0;
|
||||
}
|
||||
|
||||
return TSPoint(x, y, z);
|
||||
}
|
||||
|
||||
TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym,
|
||||
uint16_t rxplate=0) {
|
||||
_yp = yp;
|
||||
_xm = xm;
|
||||
_ym = ym;
|
||||
_xp = xp;
|
||||
_rxplate = rxplate;
|
||||
|
||||
#if defined (USE_FAST_PINIO)
|
||||
xp_port = portOutputRegister(digitalPinToPort(_xp));
|
||||
yp_port = portOutputRegister(digitalPinToPort(_yp));
|
||||
xm_port = portOutputRegister(digitalPinToPort(_xm));
|
||||
ym_port = portOutputRegister(digitalPinToPort(_ym));
|
||||
|
||||
xp_pin = digitalPinToBitMask(_xp);
|
||||
yp_pin = digitalPinToBitMask(_yp);
|
||||
xm_pin = digitalPinToBitMask(_xm);
|
||||
ym_pin = digitalPinToBitMask(_ym);
|
||||
#endif
|
||||
|
||||
pressureThreshhold = 10;
|
||||
}
|
||||
|
||||
int TouchScreen::readTouchX(void) {
|
||||
pinMode(_yp, INPUT);
|
||||
pinMode(_ym, INPUT);
|
||||
digitalWrite(_yp, LOW);
|
||||
digitalWrite(_ym, LOW);
|
||||
|
||||
pinMode(_xp, OUTPUT);
|
||||
digitalWrite(_xp, HIGH);
|
||||
pinMode(_xm, OUTPUT);
|
||||
digitalWrite(_xm, LOW);
|
||||
|
||||
return (1023-analogRead(_yp));
|
||||
}
|
||||
|
||||
|
||||
int TouchScreen::readTouchY(void) {
|
||||
pinMode(_xp, INPUT);
|
||||
pinMode(_xm, INPUT);
|
||||
digitalWrite(_xp, LOW);
|
||||
digitalWrite(_xm, LOW);
|
||||
|
||||
pinMode(_yp, OUTPUT);
|
||||
digitalWrite(_yp, HIGH);
|
||||
pinMode(_ym, OUTPUT);
|
||||
digitalWrite(_ym, LOW);
|
||||
|
||||
return (1023-analogRead(_xm));
|
||||
}
|
||||
|
||||
|
||||
uint16_t TouchScreen::pressure(void) {
|
||||
// Set X+ to ground
|
||||
pinMode(_xp, OUTPUT);
|
||||
digitalWrite(_xp, LOW);
|
||||
|
||||
// Set Y- to VCC
|
||||
pinMode(_ym, OUTPUT);
|
||||
digitalWrite(_ym, HIGH);
|
||||
|
||||
// Hi-Z X- and Y+
|
||||
digitalWrite(_xm, LOW);
|
||||
pinMode(_xm, INPUT);
|
||||
digitalWrite(_yp, LOW);
|
||||
pinMode(_yp, INPUT);
|
||||
|
||||
int z1 = analogRead(_xm);
|
||||
int z2 = analogRead(_yp);
|
||||
|
||||
if (_rxplate != 0) {
|
||||
// now read the x
|
||||
float rtouch;
|
||||
rtouch = z2;
|
||||
rtouch /= z1;
|
||||
rtouch -= 1;
|
||||
rtouch *= readTouchX();
|
||||
rtouch *= _rxplate;
|
||||
rtouch /= 1024;
|
||||
|
||||
return rtouch;
|
||||
} else {
|
||||
return (1023-(z2-z1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
# Use defaults
|
||||
@@ -0,0 +1,56 @@
|
||||
// Touch screen library with X Y and Z (pressure) readings as well
|
||||
// as oversampling to avoid 'bouncing'
|
||||
// (c) ladyada / adafruit
|
||||
// Code under MIT License
|
||||
|
||||
#ifndef _ADAFRUIT_TOUCHSCREEN_H_
|
||||
#define _ADAFRUIT_TOUCHSCREEN_H_
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(TEENSYDUINO) || defined(__AVR_ATmega2560__)
|
||||
typedef volatile uint8_t RwReg;
|
||||
#endif
|
||||
#if defined(ARDUINO_STM32_FEATHER)
|
||||
typedef volatile uint32 RwReg;
|
||||
#endif
|
||||
#if defined(NRF52_SERIES) || defined(ESP32) || defined(ARDUINO_ARCH_STM32)
|
||||
typedef volatile uint32_t RwReg;
|
||||
#endif
|
||||
|
||||
#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_SAMD)
|
||||
#define USE_FAST_PINIO
|
||||
#endif
|
||||
|
||||
class TSPoint {
|
||||
public:
|
||||
TSPoint(void);
|
||||
TSPoint(int16_t x, int16_t y, int16_t z);
|
||||
|
||||
bool operator==(TSPoint);
|
||||
bool operator!=(TSPoint);
|
||||
|
||||
int16_t x, y, z;
|
||||
};
|
||||
|
||||
class TouchScreen {
|
||||
public:
|
||||
TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, uint16_t rx);
|
||||
|
||||
bool isTouching(void);
|
||||
uint16_t pressure(void);
|
||||
int readTouchY();
|
||||
int readTouchX();
|
||||
TSPoint getPoint();
|
||||
int16_t pressureThreshhold;
|
||||
|
||||
private:
|
||||
uint8_t _yp, _ym, _xm, _xp;
|
||||
uint16_t _rxplate;
|
||||
|
||||
volatile RwReg *xp_port, *yp_port, *xm_port, *ym_port;
|
||||
RwReg xp_pin, xm_pin, yp_pin, ym_pin;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit TouchScreen
|
||||
version=1.0.4
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Adafruit TouchScreen display library.
|
||||
paragraph=Adafruit TouchScreen display library.
|
||||
category=Display
|
||||
url=https://github.com/adafruit/Adafruit_TouchScreen
|
||||
architectures=*
|
||||
1
extended-setup/components/arduino
Submodule
1
extended-setup/components/arduino
Submodule
Submodule extended-setup/components/arduino added at 79e4339582
11
extended-setup/components/drv/component.mk
Normal file
11
extended-setup/components/drv/component.mk
Normal file
@@ -0,0 +1,11 @@
|
||||
# drv
|
||||
|
||||
CFLAGS += -DLV_CONF_INCLUDE_SIMPLE
|
||||
CFLAGS += -DILI9341_BCKL_ACTIVE_LVL=0
|
||||
|
||||
# Set to 1 if your display have touch support, otherwise set it to 0.
|
||||
CFLAGS += -DTOUCH_SUPPORT=1
|
||||
|
||||
COMPONENT_SRCDIRS := .
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := $(COMPONENT_SRCDIRS) .. ../
|
||||
124
extended-setup/components/drv/disp_spi.c
Normal file
124
extended-setup/components/drv/disp_spi.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file disp_spi.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "disp_spi.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include <string.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include "freertos/task.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "ili9341.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void IRAM_ATTR spi_ready (spi_transaction_t *trans);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static spi_device_handle_t spi;
|
||||
static volatile bool spi_trans_in_progress;
|
||||
static volatile bool spi_color_sent;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
void disp_spi_init(void)
|
||||
{
|
||||
|
||||
esp_err_t ret;
|
||||
|
||||
spi_bus_config_t buscfg={
|
||||
.miso_io_num=-1,
|
||||
.mosi_io_num=DISP_SPI_MOSI,
|
||||
.sclk_io_num=DISP_SPI_CLK,
|
||||
.quadwp_io_num=-1,
|
||||
.quadhd_io_num=-1,
|
||||
.max_transfer_sz = DISP_BUF_SIZE * 2,
|
||||
};
|
||||
|
||||
spi_device_interface_config_t devcfg={
|
||||
.clock_speed_hz=80*1000*1000, //Clock out at 40 MHz
|
||||
.mode=0, //SPI mode 0
|
||||
.spics_io_num=DISP_SPI_CS, //CS pin
|
||||
.queue_size=1,
|
||||
.pre_cb=NULL,
|
||||
.post_cb=spi_ready,
|
||||
.flags = SPI_DEVICE_HALFDUPLEX
|
||||
};
|
||||
|
||||
//Initialize the SPI bus
|
||||
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret==ESP_OK);
|
||||
|
||||
//Attach the LCD to the SPI bus
|
||||
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
|
||||
assert(ret==ESP_OK);
|
||||
}
|
||||
|
||||
void disp_spi_send_data(uint8_t * data, uint16_t length)
|
||||
{
|
||||
if (length == 0) return; //no need to send anything
|
||||
|
||||
while(spi_trans_in_progress);
|
||||
|
||||
spi_transaction_t t = {
|
||||
.length = length * 8, // transaction length is in bits
|
||||
.tx_buffer = data
|
||||
};
|
||||
|
||||
spi_trans_in_progress = true;
|
||||
spi_color_sent = false; //Mark the "lv_flush_ready" NOT needs to be called in "spi_ready"
|
||||
spi_device_queue_trans(spi, &t, portMAX_DELAY);
|
||||
|
||||
}
|
||||
|
||||
void disp_spi_send_colors(uint8_t * data, uint16_t length)
|
||||
{
|
||||
if (length == 0) return; //no need to send anything
|
||||
|
||||
while(spi_trans_in_progress);
|
||||
|
||||
spi_transaction_t t = {
|
||||
.length = length * 8, // transaction length is in bits
|
||||
.tx_buffer = data
|
||||
};
|
||||
|
||||
spi_trans_in_progress = true;
|
||||
spi_color_sent = true; //Mark the "lv_flush_ready" needs to be called in "spi_ready"
|
||||
spi_device_queue_trans(spi, &t, portMAX_DELAY);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void IRAM_ATTR spi_ready (spi_transaction_t *trans)
|
||||
{
|
||||
spi_trans_in_progress = false;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(spi_color_sent) lv_disp_flush_ready(&disp->driver);
|
||||
}
|
||||
47
extended-setup/components/drv/disp_spi.h
Normal file
47
extended-setup/components/drv/disp_spi.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file disp_spi.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DISP_SPI_H
|
||||
#define DISP_SPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define DISP_SPI_MOSI CONFIG_OVC_PIN_MOSI
|
||||
#define DISP_SPI_CLK CONFIG_OVC_PIN_CLK
|
||||
#define DISP_SPI_CS CONFIG_OVC_PIN_CS
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void disp_spi_init(void);
|
||||
void disp_spi_send_data(uint8_t * data, uint16_t length);
|
||||
void disp_spi_send_colors(uint8_t * data, uint16_t length);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*DISP_SPI_H*/
|
||||
170
extended-setup/components/drv/ili9341.c
Normal file
170
extended-setup/components/drv/ili9341.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @file ili9341.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "ili9341.h"
|
||||
#include "disp_spi.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct. */
|
||||
typedef struct {
|
||||
uint8_t cmd;
|
||||
uint8_t data[16];
|
||||
uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
|
||||
} lcd_init_cmd_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void ili9341_send_cmd(uint8_t cmd);
|
||||
static void ili9341_send_data(void * data, uint16_t length);
|
||||
static void ili9341_send_color(void * data, uint16_t length);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void ili9341_init(void)
|
||||
{
|
||||
lcd_init_cmd_t ili_init_cmds[]={
|
||||
{0xCF, {0x00, 0x83, 0X30}, 3},
|
||||
{0xED, {0x64, 0x03, 0X12, 0X81}, 4},
|
||||
{0xE8, {0x85, 0x01, 0x79}, 3},
|
||||
{0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
|
||||
{0xF7, {0x20}, 1},
|
||||
{0xEA, {0x00, 0x00}, 2},
|
||||
{0xC0, {0x26}, 1}, /*Power control*/
|
||||
{0xC1, {0x11}, 1}, /*Power control */
|
||||
{0xC5, {0x35, 0x3E}, 2}, /*VCOM control*/
|
||||
{0xC7, {0xBE}, 1}, /*VCOM control*/
|
||||
{0x36, {0x28}, 1}, /*Memory Access Control*/
|
||||
{0x3A, {0x55}, 1}, /*Pixel Format Set*/
|
||||
{0xB1, {0x00, 0x1B}, 2},
|
||||
{0xF2, {0x08}, 1},
|
||||
{0x26, {0x01}, 1},
|
||||
{0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15},
|
||||
{0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15},
|
||||
{0x2A, {0x00, 0x00, 0x00, 0xEF}, 4},
|
||||
{0x2B, {0x00, 0x00, 0x01, 0x3f}, 4},
|
||||
{0x2C, {0}, 0},
|
||||
{0xB7, {0x07}, 1},
|
||||
{0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
|
||||
{0x11, {0}, 0x80},
|
||||
{0x29, {0}, 0x80},
|
||||
{0, {0}, 0xff},
|
||||
};
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(ILI9341_RST, GPIO_MODE_OUTPUT);
|
||||
// gpio_set_direction(ILI9341_BCKL, GPIO_MODE_OUTPUT);
|
||||
|
||||
//Reset the display
|
||||
gpio_set_level(ILI9341_RST, 0);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
gpio_set_level(ILI9341_RST, 1);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
|
||||
|
||||
printf("ILI9341 initialization.\n");
|
||||
|
||||
|
||||
//Send all the commands
|
||||
uint16_t cmd = 0;
|
||||
while (ili_init_cmds[cmd].databytes!=0xff) {
|
||||
ili9341_send_cmd(ili_init_cmds[cmd].cmd);
|
||||
ili9341_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F);
|
||||
if (ili_init_cmds[cmd].databytes & 0x80) {
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
}
|
||||
cmd++;
|
||||
}
|
||||
|
||||
///Enable backlight
|
||||
printf("Enable backlight.\n");
|
||||
gpio_set_level(ILI9341_BCKL, ILI9341_BCKL_ACTIVE_LVL);
|
||||
|
||||
// Change screen rotation to Portrait.
|
||||
uint8_t data[] = {0x88};
|
||||
// this same command also sets rotation (portrait/landscape) and inverts colors.
|
||||
// https://gist.github.com/motters/38a26a66020f674b6389063932048e4c#file-ili9844_defines-h-L24
|
||||
ili9341_send_cmd(0x36);
|
||||
ili9341_send_data(&data, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||
{
|
||||
uint8_t data[4];
|
||||
|
||||
/*Column addresses*/
|
||||
ili9341_send_cmd(0x2A);
|
||||
data[0] = (area->x1 >> 8) & 0xFF;
|
||||
data[1] = area->x1 & 0xFF;
|
||||
data[2] = (area->x2 >> 8) & 0xFF;
|
||||
data[3] = area->x2 & 0xFF;
|
||||
ili9341_send_data(data, 4);
|
||||
|
||||
/*Page addresses*/
|
||||
ili9341_send_cmd(0x2B);
|
||||
data[0] = (area->y1 >> 8) & 0xFF;
|
||||
data[1] = area->y1 & 0xFF;
|
||||
data[2] = (area->y2 >> 8) & 0xFF;
|
||||
data[3] = area->y2 & 0xFF;
|
||||
ili9341_send_data(data, 4);
|
||||
|
||||
/*Memory write*/
|
||||
ili9341_send_cmd(0x2C);
|
||||
|
||||
|
||||
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
||||
|
||||
ili9341_send_color((void*)color_map, size * 2);
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
static void ili9341_send_cmd(uint8_t cmd)
|
||||
{
|
||||
gpio_set_level(ILI9341_DC, 0); /*Command mode*/
|
||||
disp_spi_send_data(&cmd, 1);
|
||||
}
|
||||
|
||||
static void ili9341_send_data(void * data, uint16_t length)
|
||||
{
|
||||
gpio_set_level(ILI9341_DC, 1); /*Data mode*/
|
||||
disp_spi_send_data(data, length);
|
||||
}
|
||||
|
||||
static void ili9341_send_color(void * data, uint16_t length)
|
||||
{
|
||||
gpio_set_level(ILI9341_DC, 1); /*Data mode*/
|
||||
disp_spi_send_colors(data, length);
|
||||
}
|
||||
49
extended-setup/components/drv/ili9341.h
Normal file
49
extended-setup/components/drv/ili9341.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file lv_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILI9341_H
|
||||
#define ILI9341_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
||||
#define ILI9341_DC CONFIG_OVC_PIN_DC
|
||||
#define ILI9341_RST CONFIG_OVC_PIN_RESET
|
||||
#define ILI9341_BCKL CONFIG_OVC_PIN_LITE
|
||||
|
||||
// if text/images are backwards, try setting this to 1
|
||||
#define ILI9341_INVERT_DISPLAY 1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void ili9341_init(void);
|
||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*ILI9341_H*/
|
||||
497
extended-setup/components/lv_conf.h
Normal file
497
extended-setup/components/lv_conf.h
Normal file
@@ -0,0 +1,497 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
|
||||
*/
|
||||
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_attr.h"
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#define LV_HOR_RES_MAX (320)
|
||||
#define LV_VER_RES_MAX (240)
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 1
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
typedef int16_t lv_coord_t;
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 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 used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
# define LV_MEM_ATTR
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
# define LV_MEM_ADR 0
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded 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*/
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#define LV_INDEV_DEF_READ_PERIOD 10
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#define LV_USE_SHADOW 1
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
typedef void * lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 0
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_fs_drv_user_data_t;
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#define LV_USE_USER_DATA 0
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
|
||||
/* 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. 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.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_img_decoder_user_data_t;
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC IRAM_ATTR
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* 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
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: Enable the log module*/
|
||||
#define LV_USE_LOG 1
|
||||
#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_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`*/
|
||||
# define LV_LOG_PRINTF 1
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#define LV_FONT_ROBOTO_12 1
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#define LV_FONT_ROBOTO_22 1
|
||||
#define LV_FONT_ROBOTO_28 1
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
|
||||
/* Optionally declare your 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 from the built-in fonts*/
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
|
||||
/*=================
|
||||
* 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 " ,.;:-_"
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNM 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define LV_USE_CB 1
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#define LV_USE_CHART 1
|
||||
#if LV_USE_CHART
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#define LV_USE_GAUGE 1
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#define LV_USE_IMG 1
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#define LV_USE_IMGBTN 1
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define LV_USE_KB 1
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#define LV_USE_LED 1
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#define LV_USE_LIST 1
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#define LV_USE_LMETER 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MBOX 1
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#define LV_USE_PAGE 1
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#define LV_USE_PRELOAD 1
|
||||
#if LV_USE_PRELOAD != 0
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#define LV_USE_ROLLER 1
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define LV_USE_SW 1
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define LV_USE_TA 1
|
||||
#if LV_USE_TA != 0
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#define LV_USE_TABLE 1
|
||||
#if LV_USE_TABLE
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#define LV_USE_TABVIEW 1
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
/*Be sure every define has a default value*/
|
||||
#include "lvgl/src/lv_conf_checker.h"
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
|
||||
39
extended-setup/components/lvgl.h
Normal file
39
extended-setup/components/lvgl.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file lvgl.h
|
||||
* Include all LittleV GL related headers
|
||||
*/
|
||||
|
||||
#ifndef LVGL_H
|
||||
#define LVGL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LVGL_H*/
|
||||
97
extended-setup/components/lvgl/.clang-format
Normal file
97
extended-setup/components/lvgl/.clang-format
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '$'
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Middle
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: Never
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
7
extended-setup/components/lvgl/.editorconfig
Normal file
7
extended-setup/components/lvgl/.editorconfig
Normal file
@@ -0,0 +1,7 @@
|
||||
[*.{c,h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
14
extended-setup/components/lvgl/.github/ISSUE_TEMPLATE/all-other-issues.md
vendored
Normal file
14
extended-setup/components/lvgl/.github/ISSUE_TEMPLATE/all-other-issues.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: All other issues
|
||||
about: Questions and enhancement requests should go to the forum.
|
||||
title: ''
|
||||
labels: not-template
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# All enhancement requests or questions should be directed to the Forum.
|
||||
|
||||
|
||||
We use GitHub issues for development related discussions.
|
||||
Please use the [forum](https://forum.littlevgl.com/) to ask questions.
|
||||
27
extended-setup/components/lvgl/.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
27
extended-setup/components/lvgl/.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
Please 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 one platform.
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
||||
17
extended-setup/components/lvgl/.github/stale.yml
vendored
Normal file
17
extended-setup/components/lvgl/.github/stale.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 21
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- architecture
|
||||
- pinned
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue or pull request has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
5
extended-setup/components/lvgl/.gitignore
vendored
Normal file
5
extended-setup/components/lvgl/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
**/*.o
|
||||
**/*.swp
|
||||
**/*.swo
|
||||
tags
|
||||
docs/api_doc
|
||||
0
extended-setup/components/lvgl/.gitmodules
vendored
Normal file
0
extended-setup/components/lvgl/.gitmodules
vendored
Normal file
8
extended-setup/components/lvgl/LICENCE.txt
Normal file
8
extended-setup/components/lvgl/LICENCE.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
MIT licence
|
||||
Copyright (c) 2016 Gábor Kiss-Vámosi
|
||||
|
||||
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.
|
||||
217
extended-setup/components/lvgl/README.md
Normal file
217
extended-setup/components/lvgl/README.md
Normal file
@@ -0,0 +1,217 @@
|
||||
<h1 align="center"> LittlevGL - Open-source Embedded GUI Library</h1>
|
||||
<p align="center">
|
||||
<a href="https://github.com/littlevgl/lvgl/blob/master/LICENCE.txt"><img src="https://img.shields.io/badge/licence-MIT-blue.svg"></a>
|
||||
<a href="https://github.com/littlevgl/lvgl/releases/tag/v6.0"><img src="https://img.shields.io/badge/version-6.0-blue.svg"></a>
|
||||
<br>
|
||||
<img src="https://littlevgl.com/github/cover_ori_reduced_2.gif">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
LittlevGL provides everything you need to create a Graphical User Interface (GUI) on embedded systems with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="https://littlevgl.com">Website </a> ·
|
||||
<a href="https://littlevgl.com/live-demo">Live demo</a> ·
|
||||
<a href="https://docs.littlevgl.com/en/html/get-started/pc-simulator.html">Simulator</a> ·
|
||||
<a href="https://forum.littlevgl.com">Forum</a> ·
|
||||
<a href="https://docs.littlevgl.com/">Docs</a> ·
|
||||
<a href="https://blog.littlevgl.com/">Blog</a>
|
||||
</h4>
|
||||
|
||||
### Features
|
||||
* **Powerful building blocks** buttons, charts, lists, sliders, images, etc.
|
||||
* **Advanced graphics** with animations, anti-aliasing, opacity, smooth scrolling
|
||||
* **Simultaneously use various input devices** touchscreen, mouse, keyboard, encoder, buttons, etc.
|
||||
* **Simultaneously use multiple displays** i.e. monochrome and color display
|
||||
* **Multi-language support** with UTF-8 encoding
|
||||
* **Fully customizable** graphical elements
|
||||
* **Hardware independent** to use with any microcontroller or display
|
||||
* **Scalable** to operate with little memory (64 kB Flash, 10 kB RAM)
|
||||
* **OS, External memory and GPU** supported but not required
|
||||
* **Single frame buffer** operation even with advances graphical effects
|
||||
* **Written in C** for maximal compatibility
|
||||
* **Micropython Binding** exposes [LittlevGL API in Micropython](https://blog.littlevgl.com/2019-02-20/micropython-bindings)
|
||||
* **Simulator** to develop on PC without embedded hardware
|
||||
* **Tutorials, examples, themes** for rapid development
|
||||
* **Documentation** and API references online
|
||||
|
||||
### Supported devices
|
||||
Basically, every modern controller - which is able to drive a display - is suitable to run LittlevGL. The minimal requirements:
|
||||
- **16, 32 or 64-bit** microcontroller or processor
|
||||
- **> 16 MHz** clock speed
|
||||
- **> 16 kB RAM** for static data, dynamic data (heap), stack and display buffer (> 32 kB is recommended)
|
||||
- **> 64 kB flash** program memory (> 180 kB is recommended)
|
||||
|
||||
Just to mention some **platforms**:
|
||||
- STM32F1, STM32F3, [STM32F4](https://blog.littlevgl.com/2017-07-15/stm32f429_disco_port), [STM32F7](https://github.com/littlevgl/stm32f746_disco_no_os_sw4stm32)
|
||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
||||
- NXP Kinetis, LPC, iMX
|
||||
- [Linux frame buffer](https://blog.littlevgl.com/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/littlevgl/esp32_ili9431)
|
||||
- Nordic nrf52
|
||||
- Quectell M66
|
||||
|
||||
### Quick start in a simulator
|
||||
The easiest way to get started with LittlevGL is to run it in a simulator on your PC without any embedded hardware.
|
||||
|
||||
Choose a project with your favourite IDE:
|
||||
|
||||
| Eclipse | CodeBlocks | Visual Studio | PlatformIO | Qt Creator |
|
||||
|-------------|-------------|---------------|-----------|------------|
|
||||
| [](https://github.com/littlevgl/pc_simulator_sdl_eclipse) | [](https://github.com/littlevgl/pc_simulator_win_codeblocks) | [](https://github.com/littlevgl/visual_studio_2017_sdl_x64) | [](https://github.com/littlevgl/pc_simulator_sdl_platformio) | [](https://blog.littlevgl.com/2019-01-03/qt-creator) |
|
||||
| Cross-platform<br>with SDL | Native Windows | Cross-platform<br>with SDL | Cross-platform<br>with SDL | Cross-platform<br>with SDL |
|
||||
|
||||
### Porting to an embedded hardware
|
||||
In the most simple case you need to do these steps:
|
||||
1. Copy `lv_conf_templ.h` as `lv_conf.h` next to `lvgl` and set at least `LV_HOR_RES`, `LV_VER_RES` and `LV_COLOR_DEPTH`.
|
||||
2. Call `lv_tick_inc(x)` every `x` milliseconds **in a Timer or Task** (`x` should be between 1 and 10). It is required for the internal timing of LittlevGL. **It's very important that you don't call `lv_task_handler` in the same loop.**
|
||||
3. Call `lv_init()`
|
||||
4. Create a buffer for LittlevGL
|
||||
```c
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
|
||||
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
```
|
||||
4. Implement and register a function which can **copy a pixel array** to an area of your diplay:
|
||||
```c
|
||||
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.hor_res = 480; /*Set the horizontal resolution*/
|
||||
disp_drv.ver_res = 320; /*Set the vertical resolution*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
set_pixel(x, y, *color_p); /* Put a pixel to the display.*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp); /* Tell you are ready with the flushing*/
|
||||
}
|
||||
|
||||
```
|
||||
5. Register a function which can **read an input device**. E.g. for a touch pad:
|
||||
```c
|
||||
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
|
||||
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
|
||||
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
|
||||
|
||||
bool my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
/*Save the state and save the pressed coordinate*/
|
||||
data->state = touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
|
||||
|
||||
/*Set the coordinates (if released use the last pressed coordinates)*/
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
```
|
||||
6. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task. It will redraw the screen if required, handle input devices etc. **It's very important that you don't call `lv_tick_inc` in the same loop.**
|
||||
|
||||
For a detailed description check the [Documentation](https://docs.littlevgl.com/en/html/porting/index.html) or the [Porting examples](https://github.com/littlevgl/lvgl/tree/master/lv_porting).
|
||||
|
||||
|
||||
### Code examples
|
||||
#### Create a button with a label and assign a click callback
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button 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_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
|
||||
lv_obj_t * label = lv_label_create(btn, NULL); /*Add a label to the button*/
|
||||
lv_label_set_text(label, "Button"); /*Set the labels text*/
|
||||
|
||||
void btn_event_cb(lv_obj_t * btn, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_CLICKED) {
|
||||
printf("Clicked\n");
|
||||
}
|
||||
}
|
||||
```
|
||||

|
||||
|
||||
#### Modify the styles
|
||||
```c
|
||||
static lv_style_t style_btn_rel; /*A variable to store the released style*/
|
||||
lv_style_copy(&style_btn_rel, &lv_style_plain); /*Initialize from a built-in style*/
|
||||
style_btn_rel.body.border.color = LV_COLOR_HEX3(0x269);
|
||||
style_btn_rel.body.border.width = 1;
|
||||
style_btn_rel.body.main_color = LV_COLOR_HEX3(0xADF);
|
||||
style_btn_rel.body.grad_color = LV_COLOR_HEX3(0x46B);
|
||||
style_btn_rel.body.shadow.width = 4;
|
||||
style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
style_btn_rel.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_btn_rel.text.color = LV_COLOR_HEX3(0xDEF);
|
||||
|
||||
static lv_style_t style_btn_pr; /*A variable to store the pressed style*/
|
||||
lv_style_copy(&style_btn_pr, &style_btn_rel); /*Initialize from the released style*/
|
||||
style_btn_pr.body.border.color = LV_COLOR_HEX3(0x46B);
|
||||
style_btn_pr.body.main_color = LV_COLOR_HEX3(0x8BD);
|
||||
style_btn_pr.body.grad_color = LV_COLOR_HEX3(0x24A);
|
||||
style_btn_pr.body.shadow.width = 2;
|
||||
style_btn_pr.text.color = LV_COLOR_HEX3(0xBCD);
|
||||
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &style_btn_rel); /*Set the button's released style*/
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &style_btn_pr); /*Set the button's pressed style*/
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### Enable a fancy effect
|
||||
```c
|
||||
/*Add some effects when the button is clicked*/
|
||||
lv_btn_set_ink_in_time(btn, 300);
|
||||
lv_btn_set_ink_wait_time(btn, 100);
|
||||
lv_btn_set_ink_out_time(btn, 300);
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### Use LittlevGL from Micropython
|
||||
```python
|
||||
# Create a Button and a Label
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
|
||||
# Load the screen
|
||||
lv.scr_load(scr)
|
||||
```
|
||||
|
||||
Check out the [Documentation](https://docs.littlevgl.com/) for more!
|
||||
|
||||
### Contributing
|
||||
To ask questions please use the [Forum](https://forum.littlevgl.com).
|
||||
For development related things (bug reports, feature suggestions) use [GitHub's Issue tracker](https://github.com/littlevgl/lvgl/issues).
|
||||
You can contribute in several ways:
|
||||
- **Answer other's question** in the Forum
|
||||
- **Report and/or fix bugs** using the issue tracker and in Pull-request
|
||||
- **Suggest and/or implement new features** using the issue tracker and in Pull-request
|
||||
- **Improve and/or translate the documentation** learn more [here](https://github.com/littlevgl/docs)
|
||||
- **Write a blog post about your experiences** learn more [here](https://github.com/littlevgl/blog)
|
||||
- **Upload your project or product as a reference** to [this site](https://blog.littlevgl.com/2018-12-26/references)
|
||||
|
||||
Before contributing, please read [CONTRIBUTING.md](https://github.com/littlevgl/lvgl/blob/master/docs/CONTRIBUTING.md).
|
||||
|
||||
### Donate
|
||||
If you are pleased with the library, found it useful, or you are happy with the support you got, please help its further development:
|
||||
|
||||
[](https://littlevgl.com/donate)
|
||||
18
extended-setup/components/lvgl/component.mk
Normal file
18
extended-setup/components/lvgl/component.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
# Set simple includes as default
|
||||
ifndef LV_CONF_INCLUDE_SIMPLE
|
||||
CFLAGS += -DLV_CONF_INCLUDE_SIMPLE
|
||||
endif
|
||||
|
||||
COMPONENT_SRCDIRS := . \
|
||||
src/lv_core \
|
||||
src/lv_draw \
|
||||
src/lv_objx \
|
||||
src/lv_hal \
|
||||
src/lv_misc \
|
||||
src/lv_themes \
|
||||
src/lv_font
|
||||
COMPONENT_ADD_INCLUDEDIRS := $(COMPONENT_SRCDIRS) ../
|
||||
495
extended-setup/components/lvgl/lv_conf_template.h
Normal file
495
extended-setup/components/lvgl/lv_conf_template.h
Normal file
@@ -0,0 +1,495 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
|
||||
*/
|
||||
|
||||
#if 0 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#define LV_HOR_RES_MAX (480)
|
||||
#define LV_VER_RES_MAX (320)
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
typedef int16_t lv_coord_t;
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 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 used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
# define LV_MEM_ATTR
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
# define LV_MEM_ADR 0
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded 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*/
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#define LV_USE_SHADOW 1
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
typedef void * lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 1
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_fs_drv_user_data_t;
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#define LV_USE_USER_DATA 0
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
|
||||
/* 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. 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.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_img_decoder_user_data_t;
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* 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
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: 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_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`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
|
||||
/* Optionally declare your 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 from the built-in fonts*/
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
|
||||
/*=================
|
||||
* 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 " ,.;:-_"
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNM 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define LV_USE_CB 1
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#define LV_USE_CHART 1
|
||||
#if LV_USE_CHART
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#define LV_USE_GAUGE 1
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#define LV_USE_IMG 1
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#define LV_USE_IMGBTN 1
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define LV_USE_KB 1
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#define LV_USE_LED 1
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#define LV_USE_LIST 1
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#define LV_USE_LMETER 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MBOX 1
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#define LV_USE_PAGE 1
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#define LV_USE_PRELOAD 1
|
||||
#if LV_USE_PRELOAD != 0
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#define LV_USE_ROLLER 1
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define LV_USE_SW 1
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define LV_USE_TA 1
|
||||
#if LV_USE_TA != 0
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#define LV_USE_TABLE 1
|
||||
#if LV_USE_TABLE
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#define LV_USE_TABVIEW 1
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
/*Be sure every define has a default value*/
|
||||
#include "lvgl/src/lv_conf_checker.h"
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
92
extended-setup/components/lvgl/lvgl.h
Normal file
92
extended-setup/components/lvgl/lvgl.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @file lvgl.h
|
||||
* Include all LittleV GL related headers
|
||||
*/
|
||||
|
||||
#ifndef LVGL_H
|
||||
#define LVGL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "src/lv_version.h"
|
||||
|
||||
#include "src/lv_misc/lv_log.h"
|
||||
#include "src/lv_misc/lv_task.h"
|
||||
#include "src/lv_misc/lv_math.h"
|
||||
#include "src/lv_misc/lv_async.h"
|
||||
|
||||
#include "src/lv_hal/lv_hal.h"
|
||||
|
||||
#include "src/lv_core/lv_obj.h"
|
||||
#include "src/lv_core/lv_group.h"
|
||||
|
||||
#include "src/lv_core/lv_refr.h"
|
||||
#include "src/lv_core/lv_disp.h"
|
||||
|
||||
#include "src/lv_themes/lv_theme.h"
|
||||
|
||||
#include "src/lv_font/lv_font.h"
|
||||
#include "src/lv_font/lv_font_fmt_txt.h"
|
||||
|
||||
#include "src/lv_objx/lv_btn.h"
|
||||
#include "src/lv_objx/lv_imgbtn.h"
|
||||
#include "src/lv_objx/lv_img.h"
|
||||
#include "src/lv_objx/lv_label.h"
|
||||
#include "src/lv_objx/lv_line.h"
|
||||
#include "src/lv_objx/lv_page.h"
|
||||
#include "src/lv_objx/lv_cont.h"
|
||||
#include "src/lv_objx/lv_list.h"
|
||||
#include "src/lv_objx/lv_chart.h"
|
||||
#include "src/lv_objx/lv_table.h"
|
||||
#include "src/lv_objx/lv_cb.h"
|
||||
#include "src/lv_objx/lv_bar.h"
|
||||
#include "src/lv_objx/lv_slider.h"
|
||||
#include "src/lv_objx/lv_led.h"
|
||||
#include "src/lv_objx/lv_btnm.h"
|
||||
#include "src/lv_objx/lv_kb.h"
|
||||
#include "src/lv_objx/lv_ddlist.h"
|
||||
#include "src/lv_objx/lv_roller.h"
|
||||
#include "src/lv_objx/lv_ta.h"
|
||||
#include "src/lv_objx/lv_canvas.h"
|
||||
#include "src/lv_objx/lv_win.h"
|
||||
#include "src/lv_objx/lv_tabview.h"
|
||||
#include "src/lv_objx/lv_tileview.h"
|
||||
#include "src/lv_objx/lv_mbox.h"
|
||||
#include "src/lv_objx/lv_gauge.h"
|
||||
#include "src/lv_objx/lv_lmeter.h"
|
||||
#include "src/lv_objx/lv_sw.h"
|
||||
#include "src/lv_objx/lv_kb.h"
|
||||
#include "src/lv_objx/lv_arc.h"
|
||||
#include "src/lv_objx/lv_preload.h"
|
||||
#include "src/lv_objx/lv_calendar.h"
|
||||
#include "src/lv_objx/lv_spinbox.h"
|
||||
|
||||
#include "src/lv_draw/lv_img_cache.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LVGL_H*/
|
||||
202
extended-setup/components/lvgl/porting/lv_port_disp_template.c
Normal file
202
extended-setup/components/lvgl/porting/lv_port_disp_template.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_disp_templ.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* 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);
|
||||
#if LV_USE_GPU
|
||||
static void gpu_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void gpu_fill(lv_color_t * dest, uint32_t length, lv_color_t color);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_disp_init(void)
|
||||
{
|
||||
/*-------------------------
|
||||
* Initialize your display
|
||||
* -----------------------*/
|
||||
disp_init();
|
||||
|
||||
/*-----------------------------
|
||||
* Create a buffer for drawing
|
||||
*----------------------------*/
|
||||
|
||||
/* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
|
||||
*
|
||||
* There are three buffering configurations:
|
||||
* 1. Create ONE buffer with some rows:
|
||||
* LittlevGL will draw the display's content here and writes it to your display
|
||||
*
|
||||
* 2. Create TWO buffer with some rows:
|
||||
* LittlevGL 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 LittlevGL 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. Create TWO screen-sized buffer:
|
||||
* Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
|
||||
* whole frame to display. This way you only need to change the frame buffer's address instead of
|
||||
* copying the pixels.
|
||||
* */
|
||||
|
||||
/* Example for 1) */
|
||||
static lv_disp_buf_t disp_buf_1;
|
||||
static lv_color_t buf1_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 2) */
|
||||
static lv_disp_buf_t disp_buf_2;
|
||||
static lv_color_t buf2_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
static lv_color_t buf2_2[LV_HOR_RES_MAX * 10]; /*An other buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 3) */
|
||||
static lv_disp_buf_t disp_buf_3;
|
||||
static lv_color_t buf3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
|
||||
static lv_color_t buf3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
|
||||
lv_disp_buf_init(&disp_buf_3, buf3_1, buf3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LittlevGL
|
||||
*----------------------------------*/
|
||||
|
||||
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 = 480;
|
||||
disp_drv.ver_res = 320;
|
||||
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = disp_flush;
|
||||
|
||||
/*Set a display buffer*/
|
||||
disp_drv.buffer = &disp_buf_2;
|
||||
|
||||
#if LV_USE_GPU
|
||||
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
|
||||
|
||||
/*Blend two color array using opacity*/
|
||||
disp_drv.gpu_blend = gpu_blend;
|
||||
|
||||
/*Fill a memory array with a color*/
|
||||
disp_drv.gpu_fill = gpu_fill;
|
||||
#endif
|
||||
|
||||
/*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*/
|
||||
}
|
||||
|
||||
/* 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)*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
|
||||
/*OPTIONAL: GPU INTERFACE*/
|
||||
#if LV_USE_GPU
|
||||
|
||||
/* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity
|
||||
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
||||
static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
|
||||
{
|
||||
/*It's an example code which should be done by your GPU*/
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
dest[i] = lv_color_mix(dest[i], src[i], opa);
|
||||
}
|
||||
}
|
||||
|
||||
/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color
|
||||
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
||||
static void gpu_fill_cb(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*/
|
||||
uint32_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*/
|
||||
}
|
||||
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
dest[i] = color;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU*/
|
||||
|
||||
#else /* Enable this file at the top */
|
||||
|
||||
/* This dummy typedef exists purely to silence -Wpedantic. */
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#ifndef LV_PORT_DISP_TEMPL_H
|
||||
#define LV_PORT_DISP_TEMPL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_DISP_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
||||
379
extended-setup/components/lvgl/porting/lv_port_fs_template.c
Normal file
379
extended-setup/components/lvgl/porting/lv_port_fs_template.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_fs_templ.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* Create a type to store the required data about your file.
|
||||
* If you are using a File System library
|
||||
* it already should have a File type.
|
||||
* For example FatFS has `FIL`. In this case use `typedef FIL file_t`*/
|
||||
typedef struct {
|
||||
/*Add the data you need to store about a file*/
|
||||
uint32_t dummy1;
|
||||
uint32_t dummy2;
|
||||
}file_t;
|
||||
|
||||
/*Similarly to `file_t` create a type for directory reading too */
|
||||
typedef struct {
|
||||
/*Add the data you need to store about directory reading*/
|
||||
uint32_t dummy1;
|
||||
uint32_t dummy2;
|
||||
}dir_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void fs_init(void);
|
||||
|
||||
static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, 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);
|
||||
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 lv_fs_res_t fs_remove (lv_fs_drv_t * drv, const char *path);
|
||||
static lv_fs_res_t fs_trunc (lv_fs_drv_t * drv, void * file_p);
|
||||
static lv_fs_res_t fs_rename (lv_fs_drv_t * drv, const char * oldname, const char * newname);
|
||||
static lv_fs_res_t fs_free (lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p);
|
||||
static lv_fs_res_t fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, 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
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_fs_init(void)
|
||||
{
|
||||
/*----------------------------------------------------
|
||||
* Initialize your storage device and File System
|
||||
* -------------------------------------------------*/
|
||||
fs_init();
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Register the file system interface in LittlevGL
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/* Add a simple drive to open images */
|
||||
lv_fs_drv_t fs_drv; /*A driver descriptor*/
|
||||
memset(&fs_drv, 0, sizeof(lv_fs_drv_t)); /*Initialization*/
|
||||
|
||||
/*Set up fields...*/
|
||||
fs_drv.file_size = sizeof(file_t);
|
||||
fs_drv.letter = 'P';
|
||||
fs_drv.open = fs_open;
|
||||
fs_drv.close = fs_close;
|
||||
fs_drv.read = fs_read;
|
||||
fs_drv.write = fs_write;
|
||||
fs_drv.seek = fs_seek;
|
||||
fs_drv.tell = fs_tell;
|
||||
fs_drv.free = fs_free;
|
||||
fs_drv.size = fs_size;
|
||||
fs_drv.remove = fs_remove;
|
||||
fs_drv.rename = fs_rename;
|
||||
fs_drv.trunc = fs_trunc;
|
||||
|
||||
fs_drv.rddir_size = sizeof(dir_t);
|
||||
fs_drv.dir_close = fs_dir_close;
|
||||
fs_drv.dir_open = fs_dir_open;
|
||||
fs_drv.dir_read = fs_dir_read;
|
||||
|
||||
lv_fs_add_drv(&fs_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/* Initialize your Storage device and File system. */
|
||||
static void fs_init(void)
|
||||
{
|
||||
/*E.g. for FatFS initalize the SD card and FatFS itself*/
|
||||
|
||||
/*You code here*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable
|
||||
* @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 LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
if(mode == LV_FS_MODE_WR)
|
||||
{
|
||||
/*Open a file for write*/
|
||||
|
||||
/* Add your code here*/
|
||||
}
|
||||
else if(mode == LV_FS_MODE_RD)
|
||||
{
|
||||
/*Open a file for read*/
|
||||
|
||||
/* Add your code here*/
|
||||
}
|
||||
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
|
||||
{
|
||||
/*Open a file for read and write*/
|
||||
|
||||
/* Add your code here*/
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 lv_ufs_open)
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, the file is read
|
||||
* 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 btr Bytes To Write
|
||||
* @param br the number of real written bytes (Bytes Written). NULL if unused.
|
||||
* @return LV_FS_RES_OK 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 lv_ufs_open )
|
||||
* @param pos the new position of read write pointer
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* 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_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the size of a file bytes
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable
|
||||
* @param size pointer to a variable to store the size
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_size (lv_fs_drv_t * drv, void * file_p, uint32_t * size_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 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, the file is read
|
||||
* 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param path path of the file to delete
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_remove (lv_fs_drv_t * drv, const char *path)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the file size to the current position of the read write pointer
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_trunc (lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param oldname path to the file
|
||||
* @param newname path with the new name
|
||||
* @return LV_FS_RES_OK or any error from 'fs_res_t'
|
||||
*/
|
||||
static lv_fs_res_t fs_rename (lv_fs_drv_t * drv, const char * oldname, const char * newname)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the free and total size of a driver in kB
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param letter the driver letter
|
||||
* @param total_p pointer to store the total size [kB]
|
||||
* @param free_p pointer to store the free size [kB]
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_free (uint32_t * total_p, uint32_t * free_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a 'fs_read_dir_t' variable for directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to a 'fs_read_dir_t' variable
|
||||
* @param path path to a directory
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, const char *path)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 'fs_read_dir_t' variable
|
||||
* @param fn pointer to a buffer to store the filename
|
||||
* @return LV_FS_RES_OK 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to an initialized 'fs_read_dir_t' variable
|
||||
* @return LV_FS_RES_OK 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /* Enable this file at the top */
|
||||
|
||||
/* This dummy typedef exists purely to silence -Wpedantic. */
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
||||
44
extended-setup/components/lvgl/porting/lv_port_fs_template.h
Normal file
44
extended-setup/components/lvgl/porting/lv_port_fs_template.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#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
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_FS_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
||||
428
extended-setup/components/lvgl/porting/lv_port_indev_template.c
Normal file
428
extended-setup/components/lvgl/porting/lv_port_indev_template.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/**
|
||||
* @file lv_port_indev_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_indev_templ.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void touchpad_init(void);
|
||||
static bool 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 bool 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 bool 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 bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static void encoder_handler(void);
|
||||
|
||||
static void button_init(void);
|
||||
static bool 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
|
||||
*/
|
||||
|
||||
|
||||
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
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad 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_disp_get_scr_act(NULL), NULL);
|
||||
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_KEYPAD;
|
||||
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_keypad, 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);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
|
||||
/*------------------
|
||||
* Touchpad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad*/
|
||||
static void touchpad_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the touchpad */
|
||||
static bool 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 `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Return true is the touchpad is pressed*/
|
||||
static bool touchpad_is_pressed(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
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) = 0;
|
||||
(*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 bool 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 `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*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 bool 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 LittlevGL 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;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*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 bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
data->enc_diff = encoder_diff;
|
||||
data->state = encoder_state;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*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 bool 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;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*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
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
/**
|
||||
* @file lv_port_indev_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#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
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_INDEV_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
||||
2455
extended-setup/components/lvgl/scripts/Doxyfile
Normal file
2455
extended-setup/components/lvgl/scripts/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
import argparse
|
||||
from argparse import RawTextHelpFormatter
|
||||
import os
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description="""Create fonts for LittelvGL including the built-in symbols. lv_font_conv needs to be installed. See https://github.com/littlevgl/lv_font_conv
|
||||
Example: python built_in_font_gen.py --size 16 -o lv_font_roboto_16.c --bpp 4 -r 0x20-0x7F""", formatter_class=RawTextHelpFormatter)
|
||||
parser.add_argument('-s', '--size',
|
||||
type=int,
|
||||
metavar = 'px',
|
||||
nargs='?',
|
||||
help='Size of the font in px')
|
||||
parser.add_argument('--bpp',
|
||||
type=int,
|
||||
metavar = '1,2,4',
|
||||
nargs='?',
|
||||
help='Bit per pixel')
|
||||
parser.add_argument('-r', '--range',
|
||||
nargs='+',
|
||||
metavar = 'start-end',
|
||||
default='0x20-0x7F',
|
||||
help='Ranges and/or characters to include. Default is 0x20-7F (ASCII). E.g. -r 0x20-0x7F, 0x200, 324')
|
||||
parser.add_argument('--font',
|
||||
metavar = 'file',
|
||||
nargs='?',
|
||||
default='Roboto-Regular.woff',
|
||||
help='A TTF or WOFF file')
|
||||
parser.add_argument('-o', '--output',
|
||||
nargs='?',
|
||||
metavar='file',
|
||||
help='Output file name. E.g. my_font_20.c')
|
||||
parser.add_argument('--compressed', action='store_true',
|
||||
help='Compress the bitmaps')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.compressed == False:
|
||||
compr = "--no-compress --no-prefilter"
|
||||
else:
|
||||
compr = ""
|
||||
|
||||
#Built in symbols
|
||||
syms = "61441,61448,61451,61452,61453,61457,61459,61460,61461,61465,61468,61473,61478,61479,61480,61502,61504,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62099"
|
||||
|
||||
#Run the command
|
||||
cmd = "lv_font_conv {} --bpp {} --size {} --font ./Roboto-Regular.woff -r {} --font FontAwesome.ttf -r {} --format lvgl -o {} --force-fast-kern-format".format(compr, args.bpp, args.size, args.range[0], syms, args.output)
|
||||
os.system(cmd)
|
||||
13
extended-setup/components/lvgl/scripts/clang-formatter.sh
Executable file
13
extended-setup/components/lvgl/scripts/clang-formatter.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
clang-format-7 -style=file ../src/lv_core/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_draw/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_hal/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_misc/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_objx/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_themes/*.c -i
|
||||
|
||||
clang-format-7 -style=file ../src/lv_core/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_draw/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_hal/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_misc/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_objx/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_themes/*.h -i
|
||||
2
extended-setup/components/lvgl/scripts/cppcheck_run.sh
Executable file
2
extended-setup/components/lvgl/scripts/cppcheck_run.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
cppcheck --template="{severity}\t{file}:{line}\t{id}: {message}" --enable=all ../src/ --output-file=cppcheck_res.txt --suppress=unusedFunction --suppress=preprocessorErrorDirective --force
|
||||
|
||||
56
extended-setup/components/lvgl/scripts/lv_conf_checker.py
Normal file
56
extended-setup/components/lvgl/scripts/lv_conf_checker.py
Normal file
@@ -0,0 +1,56 @@
|
||||
'''
|
||||
Generates a checker file for lv_conf.h from lv_conf_templ.h define all the not defined values
|
||||
'''
|
||||
|
||||
|
||||
import re
|
||||
|
||||
fin = open("../lv_conf_template.h", "r")
|
||||
fout = open("../src/lv_conf_checker.h", "w")
|
||||
|
||||
|
||||
fout.write(
|
||||
'''/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_conf_checker.h
|
||||
* Make sure all the defines of lv_conf.h have a default value
|
||||
**/
|
||||
|
||||
#ifndef LV_CONF_CHECKER_H
|
||||
#define LV_CONF_CHECKER_H
|
||||
'''
|
||||
)
|
||||
|
||||
started = 0
|
||||
|
||||
for i in fin.read().splitlines():
|
||||
if not started:
|
||||
if '#define LV_CONF_H' in i:
|
||||
started = 1
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
if '/*--END OF LV_CONF_H--*/' in i: break
|
||||
|
||||
r = re.search(r'^ *# *define ([^\s]+).*$', i)
|
||||
if r:
|
||||
fout.write(
|
||||
f'#ifndef {r[1]}\n'
|
||||
f'{i}\n'
|
||||
'#endif\n'
|
||||
)
|
||||
elif re.search('^ *typedef .*;.*$', i):
|
||||
continue #ignore typedefs to avoide redeclaration
|
||||
else:
|
||||
fout.write(f'{i}\n')
|
||||
|
||||
|
||||
fout.write(
|
||||
'''
|
||||
#endif /*LV_CONF_CHECKER_H*/
|
||||
'''
|
||||
)
|
||||
|
||||
fin.close()
|
||||
fout.close()
|
||||
711
extended-setup/components/lvgl/src/lv_conf_checker.h
Normal file
711
extended-setup/components/lvgl/src/lv_conf_checker.h
Normal file
@@ -0,0 +1,711 @@
|
||||
/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_conf_checker.h
|
||||
* Make sure all the defines of lv_conf.h have a default value
|
||||
**/
|
||||
|
||||
#ifndef LV_CONF_CHECKER_H
|
||||
#define LV_CONF_CHECKER_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#ifndef LV_HOR_RES_MAX
|
||||
#define LV_HOR_RES_MAX (480)
|
||||
#endif
|
||||
#ifndef LV_VER_RES_MAX
|
||||
#define LV_VER_RES_MAX (320)
|
||||
#endif
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#ifndef LV_COLOR_DEPTH
|
||||
#define LV_COLOR_DEPTH 16
|
||||
#endif
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#ifndef LV_COLOR_16_SWAP
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
#endif
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#ifndef LV_COLOR_SCREEN_TRANSP
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
#endif
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#ifndef LV_COLOR_TRANSP
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
#endif
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#ifndef LV_ANTIALIAS
|
||||
#define LV_ANTIALIAS 1
|
||||
#endif
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#ifndef LV_DISP_DEF_REFR_PERIOD
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
#endif
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#ifndef LV_DPI
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
#endif
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
|
||||
#ifndef LV_MEM_CUSTOM
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#endif
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
#ifndef LV_MEM_SIZE
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
#endif
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
#ifndef LV_MEM_ATTR
|
||||
# define LV_MEM_ATTR
|
||||
#endif
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
#ifndef LV_MEM_ADR
|
||||
# define LV_MEM_ADR 0
|
||||
#endif
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
#ifndef LV_MEM_AUTO_DEFRAG
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#endif
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
#ifndef LV_MEM_CUSTOM_INCLUDE
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_ALLOC
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_FREE
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#ifndef LV_ENABLE_GC
|
||||
#define LV_ENABLE_GC 0
|
||||
#endif
|
||||
#if LV_ENABLE_GC != 0
|
||||
#ifndef LV_GC_INCLUDE
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_REALLOC
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_GET_SIZE
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#ifndef LV_INDEV_DEF_READ_PERIOD
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
#endif
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#ifndef LV_INDEV_DEF_DRAG_LIMIT
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
#endif
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#ifndef LV_INDEV_DEF_DRAG_THROW
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
#endif
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#ifndef LV_INDEV_DEF_LONG_PRESS_TIME
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
#endif
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#ifndef LV_INDEV_DEF_LONG_PRESS_REP_TIME
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#ifndef LV_USE_ANIMATION
|
||||
#define LV_USE_ANIMATION 1
|
||||
#endif
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#ifndef LV_USE_SHADOW
|
||||
#define LV_USE_SHADOW 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#ifndef LV_USE_GROUP
|
||||
#define LV_USE_GROUP 1
|
||||
#endif
|
||||
#if LV_USE_GROUP
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#ifndef LV_USE_GPU
|
||||
#define LV_USE_GPU 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#ifndef LV_USE_FILESYSTEM
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#endif
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#ifndef LV_USE_USER_DATA
|
||||
#define LV_USE_USER_DATA 0
|
||||
#endif
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#ifndef LV_IMG_CF_INDEXED
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#ifndef LV_IMG_CF_ALPHA
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
#endif
|
||||
|
||||
/* 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. 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.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#ifndef LV_IMG_CACHE_DEF_SIZE
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#ifndef LV_ATTRIBUTE_TICK_INC
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
#endif
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#ifndef LV_ATTRIBUTE_TASK_HANDLER
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
#endif
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* E.g. __attribute__((aligned(4))) */
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
/* Attribute to mark large constant arrays for example
|
||||
* font's bitmaps */
|
||||
#ifndef LV_ATTRIBUTE_LARGE_CONST
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
#endif
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#ifndef LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#endif
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#ifndef LV_TICK_CUSTOM_INCLUDE
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#endif
|
||||
#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: Enable the log module*/
|
||||
#ifndef LV_USE_LOG
|
||||
#define LV_USE_LOG 0
|
||||
#endif
|
||||
#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_NONE Do not log anything
|
||||
*/
|
||||
#ifndef LV_LOG_LEVEL
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
#endif
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print`*/
|
||||
#ifndef LV_LOG_PRINTF
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#ifndef LV_THEME_LIVE_UPDATE
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_THEME_TEMPL
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_DEFAULT
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_ALIEN
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_NIGHT
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_MONO
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_MATERIAL
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_ZEN
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_NEMO
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#ifndef LV_FONT_ROBOTO_12
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_16
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_22
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_28
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
#endif
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#ifndef LV_FONT_UNSCII_8
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
#endif
|
||||
|
||||
/* Optionally declare your 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)
|
||||
*/
|
||||
#ifndef LV_FONT_CUSTOM_DECLARE
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
#endif
|
||||
|
||||
/*Always set a default font from the built-in fonts*/
|
||||
#ifndef LV_FONT_DEFAULT
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
#endif
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#ifndef LV_FONT_FMT_TXT_LARGE
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*=================
|
||||
* 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
|
||||
* */
|
||||
#ifndef LV_TXT_ENC
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
#endif
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#ifndef LV_TXT_BREAK_CHARS
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
#endif
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#ifndef LV_USE_OBJ_REALIGN
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
#endif
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#ifndef LV_USE_EXT_CLICK_AREA
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#ifndef LV_USE_ARC
|
||||
#define LV_USE_ARC 1
|
||||
#endif
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#ifndef LV_USE_BAR
|
||||
#define LV_USE_BAR 1
|
||||
#endif
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#ifndef LV_USE_BTN
|
||||
#define LV_USE_BTN 1
|
||||
#endif
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
#ifndef LV_BTN_INK_EFFECT
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#ifndef LV_USE_BTNM
|
||||
#define LV_USE_BTNM 1
|
||||
#endif
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#ifndef LV_USE_CALENDAR
|
||||
#define LV_USE_CALENDAR 1
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#ifndef LV_USE_CANVAS
|
||||
#define LV_USE_CANVAS 1
|
||||
#endif
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#ifndef LV_USE_CB
|
||||
#define LV_USE_CB 1
|
||||
#endif
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#ifndef LV_USE_CHART
|
||||
#define LV_USE_CHART 1
|
||||
#endif
|
||||
#if LV_USE_CHART
|
||||
#ifndef LV_CHART_AXIS_TICK_LABEL_MAX_LEN
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#ifndef LV_USE_CONT
|
||||
#define LV_USE_CONT 1
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#ifndef LV_USE_DDLIST
|
||||
#define LV_USE_DDLIST 1
|
||||
#endif
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_DDLIST_DEF_ANIM_TIME
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#ifndef LV_USE_GAUGE
|
||||
#define LV_USE_GAUGE 1
|
||||
#endif
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#ifndef LV_USE_IMG
|
||||
#define LV_USE_IMG 1
|
||||
#endif
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#ifndef LV_USE_IMGBTN
|
||||
#define LV_USE_IMGBTN 1
|
||||
#endif
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
#ifndef LV_IMGBTN_TILED
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#ifndef LV_USE_KB
|
||||
#define LV_USE_KB 1
|
||||
#endif
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#ifndef LV_USE_LABEL
|
||||
#define LV_USE_LABEL 1
|
||||
#endif
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
#ifndef LV_LABEL_DEF_SCROLL_SPEED
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
#endif
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
#ifndef LV_LABEL_WAIT_CHAR_COUNT
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
#endif
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
#ifndef LV_LABEL_TEXT_SEL
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
#endif
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
#ifndef LV_LABEL_LONG_TXT_HINT
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#ifndef LV_USE_LED
|
||||
#define LV_USE_LED 1
|
||||
#endif
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#ifndef LV_USE_LINE
|
||||
#define LV_USE_LINE 1
|
||||
#endif
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#ifndef LV_USE_LIST
|
||||
#define LV_USE_LIST 1
|
||||
#endif
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
#ifndef LV_LIST_DEF_ANIM_TIME
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#ifndef LV_USE_LMETER
|
||||
#define LV_USE_LMETER 1
|
||||
#endif
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#ifndef LV_USE_MBOX
|
||||
#define LV_USE_MBOX 1
|
||||
#endif
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#ifndef LV_USE_PAGE
|
||||
#define LV_USE_PAGE 1
|
||||
#endif
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_PAGE_DEF_ANIM_TIME
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#ifndef LV_USE_PRELOAD
|
||||
#define LV_USE_PRELOAD 1
|
||||
#endif
|
||||
#if LV_USE_PRELOAD != 0
|
||||
#ifndef LV_PRELOAD_DEF_ARC_LENGTH
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
#endif
|
||||
#ifndef LV_PRELOAD_DEF_SPIN_TIME
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
#endif
|
||||
#ifndef LV_PRELOAD_DEF_ANIM
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#ifndef LV_USE_ROLLER
|
||||
#define LV_USE_ROLLER 1
|
||||
#endif
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_ROLLER_DEF_ANIM_TIME
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
#ifndef LV_ROLLER_INF_PAGES
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#ifndef LV_USE_SLIDER
|
||||
#define LV_USE_SLIDER 1
|
||||
#endif
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#ifndef LV_USE_SPINBOX
|
||||
#define LV_USE_SPINBOX 1
|
||||
#endif
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#ifndef LV_USE_SW
|
||||
#define LV_USE_SW 1
|
||||
#endif
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#ifndef LV_USE_TA
|
||||
#define LV_USE_TA 1
|
||||
#endif
|
||||
#if LV_USE_TA != 0
|
||||
#ifndef LV_TA_DEF_CURSOR_BLINK_TIME
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
#endif
|
||||
#ifndef LV_TA_DEF_PWD_SHOW_TIME
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#ifndef LV_USE_TABLE
|
||||
#define LV_USE_TABLE 1
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
#ifndef LV_TABLE_COL_MAX
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#ifndef LV_USE_TABVIEW
|
||||
#define LV_USE_TABVIEW 1
|
||||
#endif
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TABVIEW_DEF_ANIM_TIME
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#ifndef LV_USE_TILEVIEW
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#endif
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TILEVIEW_DEF_ANIM_TIME
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#ifndef LV_USE_WIN
|
||||
#define LV_USE_WIN 1
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_CONF_CHECKER_H*/
|
||||
11
extended-setup/components/lvgl/src/lv_core/lv_core.mk
Normal file
11
extended-setup/components/lvgl/src/lv_core/lv_core.mk
Normal file
@@ -0,0 +1,11 @@
|
||||
CSRCS += lv_group.c
|
||||
CSRCS += lv_indev.c
|
||||
CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_core
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/lvgl/src/lv_core"
|
||||
178
extended-setup/components/lvgl/src/lv_core/lv_disp.c
Normal file
178
extended-setup/components/lvgl/src/lv_core/lv_disp.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* @file lv_disp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* 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("lv_scr_act: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_load_scr(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(scr);
|
||||
|
||||
d->act_scr = scr;
|
||||
|
||||
lv_obj_invalidate(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)
|
||||
{
|
||||
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 get. (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 top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
|
||||
{
|
||||
if(lv_obj_get_parent(scr) != NULL) {
|
||||
LV_LOG_WARN("lv_disp_assign_screen: try to assign a non-screen object");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * old_disp = lv_obj_get_disp(scr);
|
||||
|
||||
if(old_disp == disp) return;
|
||||
|
||||
lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_refr_task: no display registered");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->refr_task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an 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) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_inactive_time: no display registered");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
t = LV_MATH_MIN(t, lv_tick_elaps(d->last_activity_time));
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to an 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();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
152
extended-setup/components/lvgl/src/lv_core/lv_disp.h
Normal file
152
extended-setup/components/lvgl/src/lv_core/lv_disp.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @file lv_disp.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DISP_H
|
||||
#define LV_DISP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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 get. (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);
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an 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 an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_trig_activity(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 deafult 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
||||
707
extended-setup/components/lvgl/src/lv_core/lv_group.c
Normal file
707
extended-setup/components/lvgl/src/lv_core/lv_group.c
Normal file
@@ -0,0 +1,707 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_USE_GROUP != 0
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include <stddef.h>
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style);
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style);
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th);
|
||||
static void 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 void obj_to_foreground(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
*/
|
||||
void lv_group_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
lv_mem_assert(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->click_focus = 1;
|
||||
group->editing = 0;
|
||||
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
|
||||
group->wrap = 1;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
memset(&group->user_data, 0, sizeof(lv_group_user_data_t));
|
||||
#endif
|
||||
|
||||
/*Initialize style modification callbacks from current theme*/
|
||||
refresh_theme(group, lv_theme_get_current());
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_del(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj)
|
||||
{
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
lv_mem_free(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, lv_obj_t * obj)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
|
||||
/*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("lv_group_add_obj: the object is already added to this group");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*If the object is already in a group and focused then defocus it*/
|
||||
if(obj->group_p) {
|
||||
if(lv_obj_is_focused(obj)) {
|
||||
lv_group_refocus(obj->group_p);
|
||||
|
||||
LV_LOG_INFO("lv_group_add_obj: assign object to an other group");
|
||||
}
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
lv_mem_assert(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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/
|
||||
|
||||
/*Focus on the next object*/
|
||||
if(*g->obj_focus == obj) {
|
||||
/*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) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
}
|
||||
/*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 == 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_rem(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
obj->group_p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
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)
|
||||
{
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
lv_group_t * g = obj->group_p;
|
||||
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) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
if(g->focus_cb) g->focus_cb(g);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
obj_to_foreground(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_next_core(group, lv_ll_get_head, lv_ll_get_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(en == false)
|
||||
group->frozen = 0;
|
||||
else
|
||||
group->frozen = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return LV_RES_OK;
|
||||
|
||||
lv_res_t res;
|
||||
|
||||
res = act->signal_cb(act, LV_SIGNAL_CONTROL, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
res = lv_event_send(act, LV_EVENT_KEY, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb)
|
||||
{
|
||||
group->style_mod_cb = style_mod_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus in edit mode
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_func the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb)
|
||||
{
|
||||
group->style_mod_edit_cb = style_mod_edit_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
group->focus_cb = focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_FOCUS, NULL); /*Focus again to properly leave/open edit/navigate mode*/
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
}
|
||||
|
||||
lv_obj_invalidate(focused);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en)
|
||||
{
|
||||
group->click_focus = en ? 1 : 0;
|
||||
}
|
||||
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
||||
{
|
||||
group->refocus_policy = policy & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `wrap`
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en)
|
||||
{
|
||||
group->wrap = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
* @param style pointer to a style to modify
|
||||
* @return a copy of the input style but modified with the 'style_mod' function
|
||||
*/
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
|
||||
{
|
||||
/*Load the current style. It will be modified by the callback*/
|
||||
lv_style_copy(&group->style_tmp, style);
|
||||
|
||||
if(group->editing) {
|
||||
if(group->style_mod_edit_cb) group->style_mod_edit_cb(group, &group->style_tmp);
|
||||
} else {
|
||||
if(group->style_mod_cb) group->style_mod_cb(group, &group->style_tmp);
|
||||
}
|
||||
return &group->style_tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)
|
||||
{
|
||||
return &group->user_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group in edit mode
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod_edit_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->editing ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->click_focus ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->wrap ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group)
|
||||
{
|
||||
lv_theme_t * th = lv_theme_get_current();
|
||||
|
||||
if(group != NULL) {
|
||||
refresh_theme(group, th);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_group_t * i;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_group_ll), i)
|
||||
{
|
||||
refresh_theme(i, th);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param group pointer to the caller group
|
||||
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_ORANGE;
|
||||
|
||||
/*If not transparent or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
|
||||
/*Add some recolor to the images*/
|
||||
if(style->image.intense < LV_OPA_MIN) {
|
||||
style->image.color = LV_COLOR_ORANGE;
|
||||
style->image.intense = LV_OPA_40;
|
||||
}
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 2;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param group pointer to the caller group
|
||||
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_GREEN;
|
||||
|
||||
/*If not empty or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
|
||||
/*Add some recolor to the images*/
|
||||
if(style->image.intense < LV_OPA_MIN) {
|
||||
style->image.color = LV_COLOR_GREEN;
|
||||
style->image.intense = LV_OPA_40;
|
||||
}
|
||||
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 3;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th)
|
||||
{
|
||||
g->style_mod_cb = style_mod_def;
|
||||
g->style_mod_edit_cb = style_mod_edit_def;
|
||||
if(th) {
|
||||
if(th->group.style_mod_xcb) g->style_mod_cb = th->group.style_mod_xcb;
|
||||
if(th->group.style_mod_edit_xcb) g->style_mod_edit_cb = th->group.style_mod_edit_xcb;
|
||||
}
|
||||
}
|
||||
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *))
|
||||
{
|
||||
if(group->frozen) return;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_sentinel == NULL) {
|
||||
obj_sentinel = obj_next;
|
||||
if(obj_sentinel == NULL) return; /*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;
|
||||
}
|
||||
|
||||
can_move = true;
|
||||
|
||||
if(obj_next == NULL) continue;
|
||||
|
||||
/*Hidden objects don't receive focus*/
|
||||
if(!lv_obj_get_hidden(*obj_next)) break;
|
||||
}
|
||||
|
||||
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
||||
|
||||
if(group->obj_focus) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
obj_to_foreground(*group->obj_focus);
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
if(group->focus_cb) group->focus_cb(group);
|
||||
}
|
||||
|
||||
static void obj_to_foreground(lv_obj_t * obj)
|
||||
{
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
i = lv_obj_get_parent(i);
|
||||
}
|
||||
|
||||
if(last_top != NULL) {
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_move_foreground(last_top);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
||||
293
extended-setup/components/lvgl/src/lv_core/lv_group.h
Normal file
293
extended-setup/components/lvgl/src/lv_core/lv_group.h
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
||||
/*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/
|
||||
|
||||
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;
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct _lv_group_t;
|
||||
|
||||
typedef void (*lv_group_style_mod_cb_t)(struct _lv_group_t *, lv_style_t *);
|
||||
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
|
||||
|
||||
/**
|
||||
* 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 `lv_cont` for that).
|
||||
*/
|
||||
typedef struct _lv_group_t
|
||||
{
|
||||
lv_ll_t obj_ll; /**< Linked list to store the objects in the group */
|
||||
lv_obj_t ** obj_focus; /**< The object in focus*/
|
||||
|
||||
lv_group_style_mod_cb_t style_mod_cb; /**< A function to modifies the style of the focused object*/
|
||||
lv_group_style_mod_cb_t style_mod_edit_cb; /**< A function which modifies the style of the edited object*/
|
||||
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
|
||||
lv_style_t style_tmp; /**< Stores the modified style of the focused object */
|
||||
#if LV_USE_USER_DATA
|
||||
lv_group_user_data_t 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 click_focus : 1; /**< 1: If an object in a group is clicked by an indev then it will be
|
||||
focused */
|
||||
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;
|
||||
|
||||
enum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 };
|
||||
typedef uint8_t 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);
|
||||
|
||||
/**
|
||||
* 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, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(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(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 modify the object's style if it is in focus
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus in edit mode
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_edit_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb);
|
||||
|
||||
/**
|
||||
* 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 whether the next or previous item in a group is focused if the currently focussed obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param 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 the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
* @param style pointer to a style to modify
|
||||
* @return a copy of the input style but modified with the 'style_mod' function
|
||||
*/
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group);
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group in edit mode
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(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 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 the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(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);
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
||||
1234
extended-setup/components/lvgl/src/lv_core/lv_indev.c
Normal file
1234
extended-setup/components/lvgl/src/lv_core/lv_indev.c
Normal file
File diff suppressed because it is too large
Load Diff
159
extended-setup/components/lvgl/src/lv_core/lv_indev.h
Normal file
159
extended-setup/components/lvgl/src/lv_core/lv_indev.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @file lv_indev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_INDEV_H
|
||||
#define LV_INDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the display input device subsystem
|
||||
*/
|
||||
void lv_indev_init(void);
|
||||
|
||||
/**
|
||||
* Called periodically to read the input devices
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_indev_read_task(lv_task_t * task);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void lv_indev_reset(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Reset the long press state of an input device
|
||||
* @param indev_proc pointer to an input device
|
||||
*/
|
||||
void lv_indev_reset_long_press(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Enable or disable an input devices
|
||||
* @param indev pointer to an input device
|
||||
* @param en true: enable; false: disable
|
||||
*/
|
||||
void lv_indev_enable(lv_indev_t * indev, bool en);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* 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);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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 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 if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return true: drag is in progress
|
||||
*/
|
||||
bool lv_indev_is_dragging(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the vector of dragging 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 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);
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in indev proc functions.
|
||||
* NULL if no object is currently being handled or if groups aren't used.
|
||||
* @return pointer to currently active object
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_obj_act(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_INDEV_H*/
|
||||
2337
extended-setup/components/lvgl/src/lv_core/lv_obj.c
Normal file
2337
extended-setup/components/lvgl/src/lv_core/lv_obj.c
Normal file
File diff suppressed because it is too large
Load Diff
987
extended-setup/components/lvgl/src/lv_core/lv_obj.h
Normal file
987
extended-setup/components/lvgl/src/lv_core/lv_obj.h
Normal file
@@ -0,0 +1,987 @@
|
||||
/**
|
||||
* @file lv_obj.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_H
|
||||
#define LV_OBJ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_style.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*Error check of lv_conf.h*/
|
||||
#if LV_HOR_RES_MAX == 0 || LV_VER_RES_MAX == 0
|
||||
#error "LittlevGL: LV_HOR_RES_MAX and LV_VER_RES_MAX must be greater than 0"
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS > 1
|
||||
#error "LittlevGL: LV_ANTIALIAS can be only 0 or 1"
|
||||
#endif
|
||||
|
||||
#define LV_MAX_ANCESTOR_NUM 8
|
||||
|
||||
#define LV_EXT_CLICK_AREA_OFF 0
|
||||
#define LV_EXT_CLICK_AREA_TINY 1
|
||||
#define LV_EXT_CLICK_AREA_FULL 2
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
|
||||
/** Design modes */
|
||||
enum {
|
||||
LV_DESIGN_DRAW_MAIN, /**< Draw the main portion of the object */
|
||||
LV_DESIGN_DRAW_POST, /**< Draw extras on the object */
|
||||
LV_DESIGN_COVER_CHK, /**< Check if the object fully covers the 'mask_p' area */
|
||||
};
|
||||
typedef uint8_t lv_design_mode_t;
|
||||
|
||||
/**
|
||||
* The design callback is used to draw the object on the screen.
|
||||
* It accepts the object, a mask area, and the mode in which to draw the object.
|
||||
*/
|
||||
typedef bool (*lv_design_cb_t)(struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
|
||||
|
||||
enum {
|
||||
LV_EVENT_PRESSED, /**< The object has been pressed*/
|
||||
LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/
|
||||
LV_EVENT_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */
|
||||
LV_EVENT_SHORT_CLICKED, /**< User pressed object for a short period of time, then released it. Not called if dragged. */
|
||||
LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/
|
||||
LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every
|
||||
`LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
|
||||
LV_EVENT_CLICKED, /**< Called on release if not dragged (regardless to long press)*/
|
||||
LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/
|
||||
LV_EVENT_DRAG_BEGIN,
|
||||
LV_EVENT_DRAG_END,
|
||||
LV_EVENT_DRAG_THROW_BEGIN,
|
||||
LV_EVENT_KEY,
|
||||
LV_EVENT_FOCUSED,
|
||||
LV_EVENT_DEFOCUSED,
|
||||
LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved) */
|
||||
LV_EVENT_INSERT,
|
||||
LV_EVENT_REFRESH,
|
||||
LV_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/
|
||||
LV_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/
|
||||
LV_EVENT_DELETE, /**< Object is being deleted */
|
||||
};
|
||||
typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */
|
||||
|
||||
/**
|
||||
* @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)(struct _lv_obj_t * obj, lv_event_t event);
|
||||
|
||||
/** Signals are for use by the object itself or to extend the object's functionality.
|
||||
* Applications should use ::lv_obj_set_event_cb to be notified of events that occur
|
||||
* on the object. */
|
||||
enum {
|
||||
/*General signals*/
|
||||
LV_SIGNAL_CLEANUP, /**< Object is being deleted */
|
||||
LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */
|
||||
LV_SIGNAL_CORD_CHG, /**< Object coordinates/size have changed */
|
||||
LV_SIGNAL_PARENT_SIZE_CHG, /**< Parent's size has changed */
|
||||
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
||||
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
|
||||
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
|
||||
|
||||
/*Input device related*/
|
||||
LV_SIGNAL_PRESSED, /**< The object has been pressed*/
|
||||
LV_SIGNAL_PRESSING, /**< The object is being pressed (called continuously while pressing)*/
|
||||
LV_SIGNAL_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */
|
||||
LV_SIGNAL_RELEASED, /**< User pressed object for a short period of time, then released it. Not called if dragged. */
|
||||
LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/
|
||||
LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
|
||||
LV_SIGNAL_DRAG_BEGIN,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
/*Group related*/
|
||||
LV_SIGNAL_FOCUS,
|
||||
LV_SIGNAL_DEFOCUS,
|
||||
LV_SIGNAL_CONTROL,
|
||||
LV_SIGNAL_GET_EDITABLE,
|
||||
};
|
||||
typedef uint8_t lv_signal_t;
|
||||
|
||||
typedef lv_res_t (*lv_signal_cb_t)(struct _lv_obj_t * obj, lv_signal_t sign, void * param);
|
||||
|
||||
/** Object alignment. */
|
||||
enum {
|
||||
LV_ALIGN_CENTER = 0,
|
||||
LV_ALIGN_IN_TOP_LEFT,
|
||||
LV_ALIGN_IN_TOP_MID,
|
||||
LV_ALIGN_IN_TOP_RIGHT,
|
||||
LV_ALIGN_IN_BOTTOM_LEFT,
|
||||
LV_ALIGN_IN_BOTTOM_MID,
|
||||
LV_ALIGN_IN_BOTTOM_RIGHT,
|
||||
LV_ALIGN_IN_LEFT_MID,
|
||||
LV_ALIGN_IN_RIGHT_MID,
|
||||
LV_ALIGN_OUT_TOP_LEFT,
|
||||
LV_ALIGN_OUT_TOP_MID,
|
||||
LV_ALIGN_OUT_TOP_RIGHT,
|
||||
LV_ALIGN_OUT_BOTTOM_LEFT,
|
||||
LV_ALIGN_OUT_BOTTOM_MID,
|
||||
LV_ALIGN_OUT_BOTTOM_RIGHT,
|
||||
LV_ALIGN_OUT_LEFT_TOP,
|
||||
LV_ALIGN_OUT_LEFT_MID,
|
||||
LV_ALIGN_OUT_LEFT_BOTTOM,
|
||||
LV_ALIGN_OUT_RIGHT_TOP,
|
||||
LV_ALIGN_OUT_RIGHT_MID,
|
||||
LV_ALIGN_OUT_RIGHT_BOTTOM,
|
||||
};
|
||||
typedef uint8_t lv_align_t;
|
||||
|
||||
#if LV_USE_OBJ_REALIGN
|
||||
typedef struct
|
||||
{
|
||||
const struct _lv_obj_t * base;
|
||||
lv_coord_t xofs;
|
||||
lv_coord_t yofs;
|
||||
lv_align_t align;
|
||||
uint8_t auto_realign : 1;
|
||||
uint8_t origo_align : 1; /**< 1: the origo (center of the object) was aligned with
|
||||
`lv_obj_align_origo`*/
|
||||
} lv_reailgn_t;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */
|
||||
LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */
|
||||
LV_DRAG_DIR_ALL = 0x3, /**< Object can be dragged in all directions. */
|
||||
};
|
||||
|
||||
typedef uint8_t lv_drag_dir_t;
|
||||
|
||||
typedef struct _lv_obj_t
|
||||
{
|
||||
struct _lv_obj_t * par; /**< Pointer to the parent object*/
|
||||
lv_ll_t child_ll; /**< Linked list to store the children objects*/
|
||||
|
||||
lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/
|
||||
|
||||
lv_event_cb_t event_cb; /**< Event callback function */
|
||||
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/
|
||||
lv_design_cb_t design_cb; /**< Object type specific design function*/
|
||||
|
||||
void * ext_attr; /**< Object type specific extended data*/
|
||||
const lv_style_t * style_p; /**< Pointer to the object's style*/
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
void * group_p; /**< Pointer to the group of the object*/
|
||||
#endif
|
||||
|
||||
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
|
||||
uint8_t ext_click_pad_hor; /**< Extra click padding in horizontal direction */
|
||||
uint8_t ext_click_pad_ver; /**< Extra click padding in vertical direction */
|
||||
#endif
|
||||
|
||||
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
|
||||
lv_area_t ext_click_pad; /**< Extra click padding area. */
|
||||
#endif
|
||||
|
||||
/*Attributes and states*/
|
||||
uint8_t click : 1; /**< 1: Can be pressed by an input device*/
|
||||
uint8_t drag : 1; /**< 1: Enable the dragging*/
|
||||
uint8_t drag_throw : 1; /**< 1: Enable throwing with drag*/
|
||||
uint8_t drag_parent : 1; /**< 1: Parent will be dragged instead*/
|
||||
uint8_t hidden : 1; /**< 1: Object is hidden*/
|
||||
uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/
|
||||
uint8_t opa_scale_en : 1; /**< 1: opa_scale is set*/
|
||||
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
|
||||
lv_drag_dir_t drag_dir : 2; /**< Which directions the object can be dragged in */
|
||||
uint8_t reserved : 6; /**< Reserved for future use*/
|
||||
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
|
||||
`lv_protect_t`*/
|
||||
lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/
|
||||
|
||||
lv_coord_t ext_draw_pad; /**< EXTtend the size in every direction for drawing. */
|
||||
|
||||
#if LV_USE_OBJ_REALIGN
|
||||
lv_reailgn_t realign; /**< Information about the last call to ::lv_obj_align. */
|
||||
#endif
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_obj_user_data_t user_data; /**< Custom user data for object. */
|
||||
#endif
|
||||
|
||||
} lv_obj_t;
|
||||
|
||||
/*Protect some attributes (max. 8 bit)*/
|
||||
enum {
|
||||
LV_PROTECT_NONE = 0x00,
|
||||
LV_PROTECT_CHILD_CHG = 0x01, /**< Disable the child change signal. Used by the library*/
|
||||
LV_PROTECT_PARENT = 0x02, /**< Prevent automatic parent change (e.g. in lv_page)*/
|
||||
LV_PROTECT_POS = 0x04, /**< Prevent automatic positioning (e.g. in lv_cont layout)*/
|
||||
LV_PROTECT_FOLLOW = 0x08, /**< Prevent the object be followed in automatic ordering (e.g. in
|
||||
lv_cont PRETTY layout)*/
|
||||
LV_PROTECT_PRESS_LOST = 0x10, /**< If the `indev` was pressing this object but swiped out while
|
||||
pressing do not search other object.*/
|
||||
LV_PROTECT_CLICK_FOCUS = 0x20, /**< Prevent focusing the object by clicking on it*/
|
||||
};
|
||||
typedef uint8_t lv_protect_t;
|
||||
|
||||
/** Used by `lv_obj_get_type()`. The object's and its ancestor types are stored here*/
|
||||
typedef struct
|
||||
{
|
||||
const char * type[LV_MAX_ANCESTOR_NUM]; /**< [0]: the actual type, [1]: ancestor, [2] #1's ancestor
|
||||
... [x]: "lv_obj" */
|
||||
} lv_obj_type_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the 'lv' library.
|
||||
*/
|
||||
void lv_init(void);
|
||||
|
||||
/*--------------------
|
||||
* Create and delete
|
||||
*-------------------*/
|
||||
|
||||
/**
|
||||
* Create a basic object
|
||||
* @param parent pointer to a parent object.
|
||||
* If NULL then a screen will be created
|
||||
* @param copy pointer to a base object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the new object
|
||||
*/
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy);
|
||||
|
||||
/**
|
||||
* Delete 'obj' and all of its children
|
||||
* @param obj pointer to an object to delete
|
||||
* @return LV_RES_INV because the object is deleted
|
||||
*/
|
||||
lv_res_t lv_obj_del(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Delete all children of an object
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_clean(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_invalidate(const lv_obj_t * obj);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/*--------------------
|
||||
* Parent/children set
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Set a new parent for an object. Its relative position will be the same.
|
||||
* @param obj pointer to an object. Can't be a screen.
|
||||
* @param parent pointer to the new parent object. (Can't be NULL)
|
||||
*/
|
||||
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent);
|
||||
|
||||
/**
|
||||
* Move and object to the foreground
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_move_foreground(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Move and object to the background
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_move_background(lv_obj_t * obj);
|
||||
|
||||
/*--------------------
|
||||
* Coordinate set
|
||||
* ------------------*/
|
||||
|
||||
/**
|
||||
* Set relative the position of an object (relative to the parent)
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side of the parent
|
||||
* @param y new distance from the top of the parent
|
||||
*/
|
||||
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the x coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side from the parent
|
||||
*/
|
||||
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x);
|
||||
|
||||
/**
|
||||
* Set the y coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param y new distance from the top of the parent
|
||||
*/
|
||||
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the size of an object
|
||||
* @param obj pointer to an object
|
||||
* @param w new width
|
||||
* @param h new height
|
||||
*/
|
||||
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @param w new width
|
||||
*/
|
||||
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @param h new height
|
||||
*/
|
||||
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_mod x coordinate shift after alignment
|
||||
* @param y_mod y coordinate shift after alignment
|
||||
*/
|
||||
void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);
|
||||
|
||||
/**
|
||||
* Realign the object based on the last `lv_obj_align` parameters.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_realign(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Enable the automatic realign of the object when its size has changed based on the last
|
||||
* `lv_obj_align` parameters.
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable auto realign; false: disable auto realign
|
||||
*/
|
||||
void lv_obj_set_auto_realign(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set the size of an extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @param left extended clickable are on the left [px]
|
||||
* @param right extended clickable are on the right [px]
|
||||
* @param top extended clickable are on the top [px]
|
||||
* @param bottom extended clickable are on the bottom [px]
|
||||
*/
|
||||
void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom);
|
||||
|
||||
/*---------------------
|
||||
* Appearance set
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Set a new style for an object
|
||||
* @param obj pointer to an object
|
||||
* @param style_p pointer to the new style
|
||||
*/
|
||||
void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Notify an object about its style is modified
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_refresh_style(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* 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_mod(lv_style_t * style);
|
||||
|
||||
/*-----------------
|
||||
* Attribute set
|
||||
*----------------*/
|
||||
|
||||
/**
|
||||
* Hide an object. It won't be visible and clickable.
|
||||
* @param obj pointer to an object
|
||||
* @param en true: hide the object
|
||||
*/
|
||||
void lv_obj_set_hidden(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable or disable the clicking of an object
|
||||
* @param obj pointer to an object
|
||||
* @param en true: make the object clickable
|
||||
*/
|
||||
void lv_obj_set_click(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable to bring this object to the foreground if it
|
||||
* or any of its children is clicked
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable the auto top feature
|
||||
*/
|
||||
void lv_obj_set_top(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable the dragging of an object
|
||||
* @param obj pointer to an object
|
||||
* @param en true: make the object dragable
|
||||
*/
|
||||
void lv_obj_set_drag(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set the directions an object can be dragged in
|
||||
* @param obj pointer to an object
|
||||
* @param drag_dir bitwise OR of allowed drag directions
|
||||
*/
|
||||
void lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir);
|
||||
|
||||
/**
|
||||
* Enable the throwing of an object after is is dragged
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable the drag throw
|
||||
*/
|
||||
void lv_obj_set_drag_throw(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Enable to use parent for drag related operations.
|
||||
* If trying to drag the object the parent will be moved instead
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable the 'drag parent' for the object
|
||||
*/
|
||||
void lv_obj_set_drag_parent(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Propagate the events to the parent too
|
||||
* @param obj pointer to an object
|
||||
* @param en true: enable the event propagation
|
||||
*/
|
||||
void lv_obj_set_parent_event(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
||||
* @param obj pointer to an object
|
||||
* @param en true: opa scaling is enabled for this object and all children; false: no opa scaling
|
||||
*/
|
||||
void lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set the opa scale of an object.
|
||||
* The opacity of this object and all it's children will be scaled down with this factor.
|
||||
* `lv_obj_set_opa_scale_enable(obj, true)` needs to be called to enable it.
|
||||
* (not for all children just for the parent where to start the opa scaling)
|
||||
* @param obj pointer to an object
|
||||
* @param opa_scale a factor to scale down opacity [0..255]
|
||||
*/
|
||||
void lv_obj_set_opa_scale(lv_obj_t * obj, lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* Set a bit or bits in the protect filed
|
||||
* @param obj pointer to an object
|
||||
* @param prot 'OR'-ed values from `lv_protect_t`
|
||||
*/
|
||||
void lv_obj_set_protect(lv_obj_t * obj, uint8_t prot);
|
||||
|
||||
/**
|
||||
* Clear a bit or bits in the protect filed
|
||||
* @param obj pointer to an object
|
||||
* @param prot 'OR'-ed values from `lv_protect_t`
|
||||
*/
|
||||
void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot);
|
||||
|
||||
/**
|
||||
* Set a an event handler function for an object.
|
||||
* Used by the user to react on event which happens with the object.
|
||||
* @param obj pointer to an object
|
||||
* @param event_cb the new event function
|
||||
*/
|
||||
void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);
|
||||
|
||||
/**
|
||||
* Send an event to the object
|
||||
* @param obj pointer to an object
|
||||
* @param event the type of the event from `lv_event_t`.
|
||||
* @param data arbitrary data depending on the object 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
|
||||
*/
|
||||
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data);
|
||||
|
||||
/**
|
||||
* Call an event function with an object, event, and data.
|
||||
* @param event_xcb an event callback function. If `NULL` `LV_RES_OK` will return without any actions.
|
||||
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
|
||||
* the `func_name(object, callback, ...)` convention)
|
||||
* @param obj pointer to an object to associate with the event (can be `NULL` to simply call the `event_cb`)
|
||||
* @param event an event
|
||||
* @param data pointer to a custom data
|
||||
* @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event
|
||||
*/
|
||||
lv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data);
|
||||
|
||||
/**
|
||||
* Get the `data` parameter of the current event
|
||||
* @return the `data` parameter
|
||||
*/
|
||||
const void * lv_event_get_data(void);
|
||||
|
||||
/**
|
||||
* Set the a signal function of an object. Used internally by the library.
|
||||
* Always call the previous signal function in the new.
|
||||
* @param obj pointer to an object
|
||||
* @param signal_cb the new signal function
|
||||
*/
|
||||
void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb);
|
||||
|
||||
/**
|
||||
* Send an event to the object
|
||||
* @param obj pointer to an object
|
||||
* @param event the type of the event from `lv_event_t`.
|
||||
*/
|
||||
void lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param);
|
||||
|
||||
/**
|
||||
* Set a new design function for an object
|
||||
* @param obj pointer to an object
|
||||
* @param design_cb the new design function
|
||||
*/
|
||||
void lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb);
|
||||
|
||||
/*----------------
|
||||
* Other set
|
||||
*--------------*/
|
||||
|
||||
/**
|
||||
* Allocate a new ext. data for an object
|
||||
* @param obj pointer to an object
|
||||
* @param ext_size the size of the new ext. data
|
||||
* @return pointer to the allocated ext
|
||||
*/
|
||||
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);
|
||||
|
||||
/**
|
||||
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_refresh_ext_draw_pad(lv_obj_t * obj);
|
||||
|
||||
/*=======================
|
||||
* Getter functions
|
||||
*======================*/
|
||||
|
||||
/**
|
||||
* Return with the screen of an object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to a screen
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the display of an object
|
||||
* @param scr pointer to an object
|
||||
* @return pointer the object's display
|
||||
*/
|
||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);
|
||||
|
||||
/*---------------------
|
||||
* Parent/children get
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Returns with the parent of an object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to the parent of 'obj'
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Iterate through the children of an object (start from the "youngest, lastly created")
|
||||
* @param obj pointer to an object
|
||||
* @param child NULL at first call to get the next children
|
||||
* and the previous return value later
|
||||
* @return the child after 'act_child' or NULL if no more child
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child);
|
||||
|
||||
/**
|
||||
* Iterate through the children of an object (start from the "oldest", firstly created)
|
||||
* @param obj pointer to an object
|
||||
* @param child NULL at first call to get the next children
|
||||
* and the previous return value later
|
||||
* @return the child after 'act_child' or NULL if no more child
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child);
|
||||
|
||||
/**
|
||||
* Count the children of an object (only children directly on 'obj')
|
||||
* @param obj pointer to an object
|
||||
* @return children number of 'obj'
|
||||
*/
|
||||
uint16_t lv_obj_count_children(const lv_obj_t * obj);
|
||||
|
||||
/** Recursively count the children of an object
|
||||
* @param obj pointer to an object
|
||||
* @return children number of 'obj'
|
||||
*/
|
||||
uint16_t lv_obj_count_children_recursive(const lv_obj_t * obj);
|
||||
|
||||
/*---------------------
|
||||
* Coordinate get
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Copy the coordinates of an object to an area
|
||||
* @param obj pointer to an object
|
||||
* @param cords_p pointer to an area to store the coordinates
|
||||
*/
|
||||
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p);
|
||||
|
||||
/**
|
||||
* Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.
|
||||
* (Without the size of the border or other extra graphical elements)
|
||||
* @param coords_p store the result area here
|
||||
*/
|
||||
void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p);
|
||||
|
||||
/**
|
||||
* Get the x coordinate of object
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the left side of its parent
|
||||
*/
|
||||
lv_coord_t lv_obj_get_x(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the y coordinate of object
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the top of its parent
|
||||
*/
|
||||
lv_coord_t lv_obj_get_y(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the width
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the height
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get that width reduced by the left and right padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the width which still fits into the container
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_fit(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get that height reduced by the top an bottom padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the height which still fits into the container
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_fit(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the automatic realign property of the object.
|
||||
* @param obj pointer to an object
|
||||
* @return true: auto realign is enabled; false: auto realign is disabled
|
||||
*/
|
||||
bool lv_obj_get_auto_realign(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the left padding of extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @return the extended left padding
|
||||
*/
|
||||
lv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the right padding of extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @return the extended right padding
|
||||
*/
|
||||
lv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the top padding of extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @return the extended top padding
|
||||
*/
|
||||
lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the bottom padding of extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @return the extended bottom padding
|
||||
*/
|
||||
lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the extended size attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the extended size attribute
|
||||
*/
|
||||
lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
|
||||
|
||||
/*-----------------
|
||||
* Appearance get
|
||||
*---------------*/
|
||||
|
||||
/**
|
||||
* Get the style pointer of an object (if NULL get style of the parent)
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to a style
|
||||
*/
|
||||
const lv_style_t * lv_obj_get_style(const lv_obj_t * obj);
|
||||
|
||||
/*-----------------
|
||||
* Attribute get
|
||||
*----------------*/
|
||||
|
||||
/**
|
||||
* Get the hidden attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the object is hidden
|
||||
*/
|
||||
bool lv_obj_get_hidden(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the click enable attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the object is clickable
|
||||
*/
|
||||
bool lv_obj_get_click(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the top enable attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the auto top feature is enabled
|
||||
*/
|
||||
bool lv_obj_get_top(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the drag enable attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the object is dragable
|
||||
*/
|
||||
bool lv_obj_get_drag(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the directions an object can be dragged
|
||||
* @param obj pointer to an object
|
||||
* @return bitwise OR of allowed directions an object can be dragged in
|
||||
*/
|
||||
lv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the drag throw enable attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: drag throw is enabled
|
||||
*/
|
||||
bool lv_obj_get_drag_throw(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the drag parent attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: drag parent is enabled
|
||||
*/
|
||||
bool lv_obj_get_drag_parent(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the drag parent attribute of an object
|
||||
* @param obj pointer to an object
|
||||
* @return true: drag parent is enabled
|
||||
*/
|
||||
bool lv_obj_get_parent_event(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the opa scale enable parameter
|
||||
* @param obj pointer to an object
|
||||
* @return true: opa scaling is enabled for this object and all children; false: no opa scaling
|
||||
*/
|
||||
lv_opa_t lv_obj_get_opa_scale_enable(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the opa scale parameter of an object
|
||||
* @param obj pointer to an object
|
||||
* @return opa scale [0..255]
|
||||
*/
|
||||
lv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the protect field of an object
|
||||
* @param obj pointer to an object
|
||||
* @return protect field ('OR'ed values of `lv_protect_t`)
|
||||
*/
|
||||
uint8_t lv_obj_get_protect(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Check at least one bit of a given protect bitfield is set
|
||||
* @param obj pointer to an object
|
||||
* @param prot protect bits to test ('OR'ed values of `lv_protect_t`)
|
||||
* @return false: none of the given bits are set, true: at least one bit is set
|
||||
*/
|
||||
bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot);
|
||||
|
||||
/**
|
||||
* Get the signal function of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the signal function
|
||||
*/
|
||||
lv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the design function of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the design function
|
||||
*/
|
||||
lv_design_cb_t lv_obj_get_design_cb(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the event function of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the event function
|
||||
*/
|
||||
lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj);
|
||||
|
||||
/*------------------
|
||||
* Other get
|
||||
*-----------------*/
|
||||
|
||||
/**
|
||||
* Get the ext pointer
|
||||
* @param obj pointer to an object
|
||||
* @return the ext pointer but not the dynamic version
|
||||
* Use it as ext->data1, and NOT da(ext)->data1
|
||||
*/
|
||||
void * lv_obj_get_ext_attr(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.
|
||||
* E.g. buf.type[0]="lv_btn", buf.type[1]="lv_cont", buf.type[2]="lv_obj"
|
||||
* @param obj pointer to an object which type should be get
|
||||
* @param buf pointer to an `lv_obj_type_t` buffer to store the types
|
||||
*/
|
||||
void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf);
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get the object's user data
|
||||
* @param obj pointer to an object
|
||||
* @return user data
|
||||
*/
|
||||
lv_obj_user_data_t lv_obj_get_user_data(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get a pointer to the object's user data
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the object's user data. The data will be copied.
|
||||
* @param obj pointer to an object
|
||||
* @param data user data
|
||||
*/
|
||||
void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data);
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Tell whether the object is the focused object of a group or not.
|
||||
* @param obj pointer to an object
|
||||
* @return true: the object is focused, false: the object is not focused or not in a group
|
||||
*/
|
||||
bool lv_obj_is_focused(const lv_obj_t * obj);
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Helps to quickly declare an event callback function.
|
||||
* Will be expanded to: `void <name> (lv_obj_t * obj, lv_event_t e)`
|
||||
*
|
||||
* Examples:
|
||||
* static LV_EVENT_CB_DECLARE(my_event1); //Protoype declaration
|
||||
*
|
||||
* static LV_EVENT_CB_DECLARE(my_event1)
|
||||
* {
|
||||
* if(e == LV_EVENT_CLICKED) {
|
||||
* lv_obj_set_hidden(obj ,true);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
#define LV_EVENT_CB_DECLARE(name) void name(lv_obj_t * obj, lv_event_t e)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_H*/
|
||||
583
extended-setup/components/lvgl/src/lv_core/lv_refr.c
Normal file
583
extended-setup/components/lvgl/src/lv_core/lv_refr.c
Normal file
@@ -0,0 +1,583 @@
|
||||
/**
|
||||
* @file lv_refr.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_refr.h"
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_hal/lv_hal_disp.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/* Draw translucent random colored areas on the invalidated (redrawn) areas*/
|
||||
#define MASK_AREA_DEBUG 0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_refr_join_area(void);
|
||||
static void lv_refr_areas(void);
|
||||
static void lv_refr_area(const lv_area_t * area_p);
|
||||
static void lv_refr_area_part(const lv_area_t * area_p);
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj);
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p);
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
|
||||
static void lv_refr_vdb_flush(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t px_num;
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the 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)
|
||||
{
|
||||
if(disp) {
|
||||
lv_disp_refr_task(disp->refr_task);
|
||||
} else {
|
||||
lv_disp_t * d;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
lv_disp_refr_task(d->refr_task);
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) return;
|
||||
|
||||
/*Clear the invalidate buffer if the parameter is NULL*/
|
||||
if(area_p == NULL) {
|
||||
disp->inv_p = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t scr_area;
|
||||
scr_area.x1 = 0;
|
||||
scr_area.y1 = 0;
|
||||
scr_area.x2 = lv_disp_get_hor_res(disp) - 1;
|
||||
scr_area.y2 = lv_disp_get_ver_res(disp) - 1;
|
||||
|
||||
lv_area_t com_area;
|
||||
bool suc;
|
||||
|
||||
suc = lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
|
||||
/*The area is truncated to the screen*/
|
||||
if(suc != false) {
|
||||
if(disp->driver.rounder_cb) disp->driver.rounder_cb(&disp_refr->driver, &com_area);
|
||||
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < disp->inv_p; i++) {
|
||||
if(lv_area_is_in(&com_area, &disp->inv_areas[i]) != false) return;
|
||||
}
|
||||
|
||||
/*Save the area*/
|
||||
if(disp->inv_p < LV_INV_BUF_SIZE) {
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &com_area);
|
||||
} else { /*If no place for the area add the screen*/
|
||||
disp->inv_p = 0;
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);
|
||||
}
|
||||
disp->inv_p++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * lv_refr_get_disp_refreshing(void)
|
||||
{
|
||||
return disp_refr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn1t 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)
|
||||
{
|
||||
disp_refr = disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("lv_refr_task: started");
|
||||
|
||||
uint32_t start = lv_tick_get();
|
||||
|
||||
disp_refr = task->user_data;
|
||||
|
||||
lv_refr_join_area();
|
||||
|
||||
lv_refr_areas();
|
||||
|
||||
/*If refresh happened ...*/
|
||||
if(disp_refr->inv_p != 0) {
|
||||
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to
|
||||
* date*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
|
||||
/* With true double buffering the flushing should be only the address change of the
|
||||
* current frame buffer. Wait until the address change is ready and copy the changed
|
||||
* content to the other frame buffer (new active VDB) to keep the buffers synchronized*/
|
||||
while(vdb->flushing)
|
||||
;
|
||||
|
||||
uint8_t * buf_act = (uint8_t *)vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
lv_coord_t y;
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*End of true double buffer handling*/
|
||||
|
||||
/*Clean up*/
|
||||
memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));
|
||||
memset(disp_refr->inv_area_joined, 0, sizeof(disp_refr->inv_area_joined));
|
||||
disp_refr->inv_p = 0;
|
||||
|
||||
/*Call monitor cb if present*/
|
||||
if(disp_refr->driver.monitor_cb) {
|
||||
disp_refr->driver.monitor_cb(&disp_refr->driver, lv_tick_elaps(start), px_num);
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_free_buf();
|
||||
|
||||
LV_LOG_TRACE("lv_refr_task: ready");
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Join the areas which has got common parts
|
||||
*/
|
||||
static void lv_refr_join_area(void)
|
||||
{
|
||||
uint32_t join_from;
|
||||
uint32_t join_in;
|
||||
lv_area_t joined_area;
|
||||
for(join_in = 0; join_in < disp_refr->inv_p; join_in++) {
|
||||
if(disp_refr->inv_area_joined[join_in] != 0) continue;
|
||||
|
||||
/*Check all areas to join them in 'join_in'*/
|
||||
for(join_from = 0; join_from < disp_refr->inv_p; join_from++) {
|
||||
/*Handle only unjoined areas and ignore itself*/
|
||||
if(disp_refr->inv_area_joined[join_from] != 0 || join_in == join_from) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Check if the areas are on each other*/
|
||||
if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
|
||||
|
||||
/*Join two area only if the joined area size is smaller*/
|
||||
if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) +
|
||||
lv_area_get_size(&disp_refr->inv_areas[join_from]))) {
|
||||
lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);
|
||||
|
||||
/*Mark 'join_form' is joined into 'join_in'*/
|
||||
disp_refr->inv_area_joined[join_from] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the joined areas
|
||||
*/
|
||||
static void lv_refr_areas(void)
|
||||
{
|
||||
px_num = 0;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < disp_refr->inv_p; i++) {
|
||||
/*Refresh the unjoined areas*/
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
|
||||
lv_refr_area(&disp_refr->inv_areas[i]);
|
||||
|
||||
if(disp_refr->driver.monitor_cb) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an area if there is Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area(const lv_area_t * area_p)
|
||||
{
|
||||
/*True double buffering: there are two screen sized buffers. Just redraw directly into a
|
||||
* buffer*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
vdb->area.x1 = 0;
|
||||
vdb->area.x2 = lv_disp_get_hor_res(disp_refr) - 1;
|
||||
vdb->area.y1 = 0;
|
||||
vdb->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
/*The buffer is smaller: refresh the area in parts*/
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
/*Calculate the max row num*/
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
lv_coord_t y2 =
|
||||
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? y2 = lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t)vdb->size / w;
|
||||
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
/*Round down the lines of VDB if rounding is added*/
|
||||
if(disp_refr->driver.rounder_cb) {
|
||||
lv_area_t tmp;
|
||||
tmp.x1 = 0;
|
||||
tmp.x2 = 0;
|
||||
tmp.y1 = 0;
|
||||
|
||||
lv_coord_t y_tmp = max_row - 1;
|
||||
do {
|
||||
tmp.y2 = y_tmp;
|
||||
disp_refr->driver.rounder_cb(&disp_refr->driver, &tmp);
|
||||
|
||||
/*If this height fits into `max_row` then fine*/
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
y_tmp--;
|
||||
} while(y_tmp != 0);
|
||||
|
||||
if(y_tmp == 0) {
|
||||
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to "
|
||||
"small VDB)");
|
||||
return;
|
||||
} else {
|
||||
max_row = tmp.y2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*Always use the full row*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = row + max_row - 1;
|
||||
if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
row_last = vdb->area.y2;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(y2 != row_last) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = y2;
|
||||
|
||||
/*Refresh this part too*/
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a part of an area which is on the actual Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
{
|
||||
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In non double buffered mode, before rendering the next part wait until the previous image is
|
||||
* flushed*/
|
||||
if(lv_disp_is_double_buf(disp_refr) == false) {
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
lv_obj_t * top_p;
|
||||
|
||||
/*Get the new mask from the original area and the act. VDB
|
||||
It will be a part of 'area_p'*/
|
||||
lv_area_t start_mask;
|
||||
lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
|
||||
/*Get the most top object which is not covered by others*/
|
||||
top_p = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_p, &start_mask);
|
||||
|
||||
/*Also refresh top and sys layer unconditionally*/
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_sys(disp_refr), &start_mask);
|
||||
|
||||
/* In true double buffered mode flush only once when all areas were rendered.
|
||||
* In normal mode flush after every area */
|
||||
if(lv_disp_is_true_double_buf(disp_refr) == false) {
|
||||
lv_refr_vdb_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the most top object which fully covers an area
|
||||
* @param area_p pointer to an area
|
||||
* @param obj the first object to start the searching (typically a screen)
|
||||
* @return
|
||||
*/
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0) {
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
found_p = lv_refr_get_top_obj(area_p, i);
|
||||
|
||||
/*If a children is ok then break*/
|
||||
if(found_p != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*If no better children check this object*/
|
||||
if(found_p == NULL) {
|
||||
const lv_style_t * style = lv_obj_get_style(obj);
|
||||
if(style->body.opa == LV_OPA_COVER && obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) != false &&
|
||||
lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
|
||||
found_p = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the refreshing from an object. Draw all its children and the youngers too.
|
||||
* @param top_p pointer to an objects. Start the drawing from it.
|
||||
* @param mask_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
{
|
||||
/* Normally always will be a top_obj (at least the screen)
|
||||
* but in special cases (e.g. if the screen has alpha) it won't.
|
||||
* In this case use the screen directly */
|
||||
if(top_p == NULL) top_p = lv_disp_get_scr_act(disp_refr);
|
||||
|
||||
/*Refresh the top object and its children*/
|
||||
lv_refr_obj(top_p, mask_p);
|
||||
|
||||
/*Draw the 'younger' sibling objects because they can be on top_obj */
|
||||
lv_obj_t * par;
|
||||
lv_obj_t * border_p = top_p;
|
||||
|
||||
par = lv_obj_get_parent(top_p);
|
||||
|
||||
/*Do until not reach the screen*/
|
||||
while(par != NULL) {
|
||||
/*object before border_p has to be redrawn*/
|
||||
lv_obj_t * i = lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
|
||||
while(i != NULL) {
|
||||
/*Refresh the objects*/
|
||||
lv_refr_obj(i, mask_p);
|
||||
i = lv_ll_get_prev(&(par->child_ll), i);
|
||||
}
|
||||
|
||||
/*Call the post draw design function of the parents of the to object*/
|
||||
par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
|
||||
|
||||
/*The new border will be there last parents,
|
||||
*so the 'younger' brothers of parent will be refreshed*/
|
||||
border_p = par;
|
||||
/*Go a level deeper*/
|
||||
par = lv_obj_get_parent(par);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an object an all of its children. (Called recursively)
|
||||
* @param obj pointer to an object to refresh
|
||||
* @param mask_ori_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
{
|
||||
/*Do not refresh hidden objects*/
|
||||
if(obj->hidden != 0) return;
|
||||
|
||||
bool union_ok; /* Store the return value of area_union */
|
||||
/* Truncate the original mask to the coordinates of the parent
|
||||
* because the parent and its children are visible only here */
|
||||
lv_area_t obj_mask;
|
||||
lv_area_t obj_ext_mask;
|
||||
lv_area_t obj_area;
|
||||
lv_coord_t ext_size = obj->ext_draw_pad;
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
obj_area.x1 -= ext_size;
|
||||
obj_area.y1 -= ext_size;
|
||||
obj_area.x2 += ext_size;
|
||||
obj_area.y2 += ext_size;
|
||||
union_ok = lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
|
||||
|
||||
/*Draw the parent and its children only if they ore on 'mask_parent'*/
|
||||
if(union_ok != false) {
|
||||
|
||||
/* Redraw the object */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
|
||||
|
||||
#if MASK_AREA_DEBUG
|
||||
static lv_color_t debug_color = LV_COLOR_RED;
|
||||
lv_draw_fill(&obj_ext_mask, &obj_ext_mask, debug_color, LV_OPA_50);
|
||||
debug_color.full *= 17;
|
||||
debug_color.full += 0xA1;
|
||||
#endif
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
union_ok = lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
|
||||
if(union_ok != false) {
|
||||
lv_area_t mask_child; /*Mask from obj and its child*/
|
||||
lv_obj_t * child_p;
|
||||
lv_area_t child_area;
|
||||
LV_LL_READ_BACK(obj->child_ll, child_p)
|
||||
{
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_draw_pad;
|
||||
child_area.x1 -= ext_size;
|
||||
child_area.y1 -= ext_size;
|
||||
child_area.x2 += ext_size;
|
||||
child_area.y2 += ext_size;
|
||||
/* Get the union (common parts) of original mask (from obj)
|
||||
* and its child */
|
||||
union_ok = lv_area_intersect(&mask_child, &obj_mask, &child_area);
|
||||
|
||||
/*If the parent and the child has common area then refresh the child */
|
||||
if(union_ok) {
|
||||
/*Refresh the next children*/
|
||||
lv_refr_obj(child_p, &mask_child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If all the children are redrawn make 'post draw' design */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the content of the VDB
|
||||
*/
|
||||
static void lv_refr_vdb_flush(void)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In double buffered mode wait until the other buffer is flushed before flushing the current
|
||||
* one*/
|
||||
if(lv_disp_is_double_buf(disp_refr)) {
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
vdb->flushing = 1;
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act);
|
||||
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
if(vdb->buf_act == vdb->buf1)
|
||||
vdb->buf_act = vdb->buf2;
|
||||
else
|
||||
vdb->buf_act = vdb->buf1;
|
||||
}
|
||||
}
|
||||
93
extended-setup/components/lvgl/src/lv_core/lv_refr.h
Normal file
93
extended-setup/components/lvgl/src/lv_core/lv_refr.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @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
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* 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_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the 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);
|
||||
|
||||
/**
|
||||
* 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 shouldn1t 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);
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_REFR_H*/
|
||||
346
extended-setup/components/lvgl/src/lv_core/lv_style.c
Normal file
346
extended-setup/components/lvgl/src/lv_core/lv_style.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/**
|
||||
* @file lv_style.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define STYLE_MIX_MAX 256
|
||||
#define STYLE_MIX_SHIFT 8 /*log2(STYLE_MIX_MAX)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2 - v1) * r) >> STYLE_MIX_SHIFT)
|
||||
#define STYLE_ATTR_MIX(attr, r) \
|
||||
if(start->attr != end->attr) { \
|
||||
res->attr = VAL_PROP(start->attr, end->attr, r); \
|
||||
} else { \
|
||||
res->attr = start->attr; \
|
||||
}
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#if LV_USE_ANIMATION
|
||||
static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val);
|
||||
static void style_animation_common_end_cb(lv_anim_t * a);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
lv_style_t lv_style_scr;
|
||||
lv_style_t lv_style_transp;
|
||||
lv_style_t lv_style_transp_fit;
|
||||
lv_style_t lv_style_transp_tight;
|
||||
lv_style_t lv_style_plain;
|
||||
lv_style_t lv_style_plain_color;
|
||||
lv_style_t lv_style_pretty;
|
||||
lv_style_t lv_style_pretty_color;
|
||||
lv_style_t lv_style_btn_rel;
|
||||
lv_style_t lv_style_btn_pr;
|
||||
lv_style_t lv_style_btn_tgl_rel;
|
||||
lv_style_t lv_style_btn_tgl_pr;
|
||||
lv_style_t lv_style_btn_ina;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the basic styles
|
||||
*/
|
||||
void lv_style_init(void)
|
||||
{
|
||||
/* Not White/Black/Gray colors are created by HSV model with
|
||||
* HUE = 210*/
|
||||
|
||||
/*Screen style*/
|
||||
lv_style_scr.glass = 0;
|
||||
lv_style_scr.body.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.radius = 0;
|
||||
lv_style_scr.body.padding.left = 0;
|
||||
lv_style_scr.body.padding.right = 0;
|
||||
lv_style_scr.body.padding.top = 0;
|
||||
lv_style_scr.body.padding.bottom = 0;
|
||||
lv_style_scr.body.padding.inner = LV_DPI / 20;
|
||||
|
||||
lv_style_scr.body.border.color = LV_COLOR_BLACK;
|
||||
lv_style_scr.body.border.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.border.width = 0;
|
||||
lv_style_scr.body.border.part = LV_BORDER_FULL;
|
||||
|
||||
lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
|
||||
lv_style_scr.body.shadow.width = 0;
|
||||
|
||||
lv_style_scr.text.opa = LV_OPA_COVER;
|
||||
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
|
||||
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_scr.text.font = LV_FONT_DEFAULT;
|
||||
lv_style_scr.text.letter_space = 0;
|
||||
lv_style_scr.text.line_space = 2;
|
||||
|
||||
lv_style_scr.image.opa = LV_OPA_COVER;
|
||||
lv_style_scr.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.image.intense = LV_OPA_TRANSP;
|
||||
|
||||
lv_style_scr.line.opa = LV_OPA_COVER;
|
||||
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.rounded = 0;
|
||||
|
||||
/*Plain style (by default near the same as the screen style)*/
|
||||
lv_style_copy(&lv_style_plain, &lv_style_scr);
|
||||
lv_style_plain.body.padding.left = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.right = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.top = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.bottom = LV_DPI / 20;
|
||||
|
||||
/*Plain color style*/
|
||||
lv_style_copy(&lv_style_plain_color, &lv_style_plain);
|
||||
lv_style_plain_color.text.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.image.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.line.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.body.main_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
|
||||
|
||||
/*Pretty style */
|
||||
lv_style_copy(&lv_style_pretty, &lv_style_plain);
|
||||
lv_style_pretty.text.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
|
||||
lv_style_pretty.body.radius = LV_DPI / 15;
|
||||
lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);
|
||||
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_pretty.body.border.opa = LV_OPA_30;
|
||||
|
||||
/*Pretty color style*/
|
||||
lv_style_copy(&lv_style_pretty_color, &lv_style_pretty);
|
||||
lv_style_pretty_color.text.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.image.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.line.color = lv_color_make(0xc0, 0xc0, 0xc0);
|
||||
lv_style_pretty_color.body.main_color = lv_color_make(0x6b, 0x9a, 0xc7);
|
||||
lv_style_pretty_color.body.grad_color = lv_color_make(0x2b, 0x59, 0x8b);
|
||||
lv_style_pretty_color.body.border.color = lv_color_make(0x15, 0x2c, 0x42);
|
||||
|
||||
/*Transparent style*/
|
||||
lv_style_copy(&lv_style_transp, &lv_style_plain);
|
||||
lv_style_transp.glass = 1;
|
||||
lv_style_transp.body.border.width = 0;
|
||||
lv_style_transp.body.opa = LV_OPA_TRANSP;
|
||||
|
||||
/*Transparent fitting size*/
|
||||
lv_style_copy(&lv_style_transp_fit, &lv_style_transp);
|
||||
lv_style_transp_fit.body.padding.left = 0;
|
||||
lv_style_transp_fit.body.padding.right = 0;
|
||||
lv_style_transp_fit.body.padding.top = 0;
|
||||
lv_style_transp_fit.body.padding.bottom = 0;
|
||||
|
||||
/*Transparent tight style*/
|
||||
lv_style_copy(&lv_style_transp_tight, &lv_style_transp_fit);
|
||||
lv_style_transp_tight.body.padding.inner = 0;
|
||||
|
||||
/*Button released style*/
|
||||
lv_style_copy(&lv_style_btn_rel, &lv_style_plain);
|
||||
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
|
||||
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
|
||||
lv_style_btn_rel.body.radius = LV_DPI / 15;
|
||||
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.top = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
|
||||
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
|
||||
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_btn_rel.body.border.opa = LV_OPA_70;
|
||||
lv_style_btn_rel.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_btn_rel.body.shadow.width = 0;
|
||||
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
|
||||
/*Button pressed style*/
|
||||
lv_style_copy(&lv_style_btn_pr, &lv_style_btn_rel);
|
||||
lv_style_btn_pr.body.main_color = lv_color_make(0x33, 0x62, 0x94);
|
||||
lv_style_btn_pr.body.grad_color = lv_color_make(0x10, 0x26, 0x3c);
|
||||
lv_style_btn_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button toggle released style*/
|
||||
lv_style_copy(&lv_style_btn_tgl_rel, &lv_style_btn_rel);
|
||||
lv_style_btn_tgl_rel.body.main_color = lv_color_make(0x0a, 0x11, 0x22);
|
||||
lv_style_btn_tgl_rel.body.grad_color = lv_color_make(0x37, 0x62, 0x90);
|
||||
lv_style_btn_tgl_rel.body.border.color = lv_color_make(0x01, 0x07, 0x0d);
|
||||
lv_style_btn_tgl_rel.text.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.image.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.line.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
|
||||
/*Button toggle pressed style*/
|
||||
lv_style_copy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel);
|
||||
lv_style_btn_tgl_pr.body.main_color = lv_color_make(0x02, 0x14, 0x27);
|
||||
lv_style_btn_tgl_pr.body.grad_color = lv_color_make(0x2b, 0x4c, 0x70);
|
||||
lv_style_btn_tgl_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button inactive style*/
|
||||
lv_style_copy(&lv_style_btn_ina, &lv_style_btn_rel);
|
||||
lv_style_btn_ina.body.main_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.grad_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.border.color = lv_color_make(0x90, 0x90, 0x90);
|
||||
lv_style_btn_ina.text.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.image.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.line.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(lv_style_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
* @param end end style
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)
|
||||
{
|
||||
STYLE_ATTR_MIX(body.opa, ratio);
|
||||
STYLE_ATTR_MIX(body.radius, ratio);
|
||||
STYLE_ATTR_MIX(body.border.width, ratio);
|
||||
STYLE_ATTR_MIX(body.border.opa, ratio);
|
||||
STYLE_ATTR_MIX(body.shadow.width, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.left, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.right, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.top, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.bottom, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.inner, ratio);
|
||||
STYLE_ATTR_MIX(text.line_space, ratio);
|
||||
STYLE_ATTR_MIX(text.letter_space, ratio);
|
||||
STYLE_ATTR_MIX(text.opa, ratio);
|
||||
STYLE_ATTR_MIX(line.width, ratio);
|
||||
STYLE_ATTR_MIX(line.opa, ratio);
|
||||
STYLE_ATTR_MIX(image.intense, ratio);
|
||||
STYLE_ATTR_MIX(image.opa, ratio);
|
||||
|
||||
lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;
|
||||
|
||||
res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
|
||||
res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
|
||||
res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
|
||||
res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
|
||||
res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
|
||||
res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
|
||||
res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
|
||||
|
||||
if(ratio < (STYLE_MIX_MAX >> 1)) {
|
||||
res->body.border.part = start->body.border.part;
|
||||
res->glass = start->glass;
|
||||
res->text.font = start->text.font;
|
||||
res->body.shadow.type = start->body.shadow.type;
|
||||
res->line.rounded = start->line.rounded;
|
||||
} else {
|
||||
res->body.border.part = end->body.border.part;
|
||||
res->glass = end->glass;
|
||||
res->text.font = end->text.font;
|
||||
res->body.shadow.type = end->body.shadow.type;
|
||||
res->line.rounded = end->line.rounded;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
void lv_style_anim_init(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_init(a);
|
||||
a->start = 0;
|
||||
a->end = STYLE_MIX_MAX;
|
||||
a->exec_cb = (lv_anim_exec_xcb_t)style_animator;
|
||||
a->path_cb = lv_anim_path_linear;
|
||||
a->ready_cb = style_animation_common_end_cb;
|
||||
|
||||
lv_style_anim_dsc_t * dsc;
|
||||
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
|
||||
lv_mem_assert(dsc);
|
||||
if(dsc == NULL) return;
|
||||
dsc->ready_cb = NULL;
|
||||
dsc->style_anim = NULL;
|
||||
lv_style_copy(&dsc->style_start, &lv_style_plain);
|
||||
lv_style_copy(&dsc->style_end, &lv_style_plain);
|
||||
|
||||
a->var = (void *)dsc;
|
||||
}
|
||||
|
||||
void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end)
|
||||
{
|
||||
|
||||
lv_style_anim_dsc_t * dsc = a->var;
|
||||
dsc->style_anim = to_anim;
|
||||
memcpy(&dsc->style_start, start, sizeof(lv_style_t));
|
||||
memcpy(&dsc->style_end, end, sizeof(lv_style_t));
|
||||
memcpy(dsc->style_anim, start, sizeof(lv_style_t));
|
||||
}
|
||||
#endif
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
#if LV_USE_ANIMATION
|
||||
/**
|
||||
* Used by the style animations to set the values of a style according to start and end style.
|
||||
* @param dsc the 'animated variable' set by lv_style_anim_create()
|
||||
* @param val the current state of the animation between 0 and LV_ANIM_RESOLUTION
|
||||
*/
|
||||
static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val)
|
||||
{
|
||||
const lv_style_t * start = &dsc->style_start;
|
||||
const lv_style_t * end = &dsc->style_end;
|
||||
lv_style_t * act = dsc->style_anim;
|
||||
|
||||
lv_style_mix(start, end, act, val);
|
||||
|
||||
lv_obj_report_style_mod(dsc->style_anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a style animation is ready
|
||||
* It called the user defined call back and free the allocated memories
|
||||
* @param a pointer to the animation
|
||||
*/
|
||||
static void style_animation_common_end_cb(lv_anim_t * a)
|
||||
{
|
||||
|
||||
(void)a; /*Unused*/
|
||||
lv_style_anim_dsc_t * dsc = a->var; /*To avoid casting*/
|
||||
|
||||
if(dsc->ready_cb) dsc->ready_cb(a);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
|
||||
#endif
|
||||
279
extended-setup/components/lvgl/src/lv_core/lv_style.h
Normal file
279
extended-setup/components/lvgl/src/lv_core/lv_style.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file lv_style.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_STYLE_H
|
||||
#define LV_STYLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdbool.h>
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Border types (Use 'OR'ed values)*/
|
||||
enum {
|
||||
LV_BORDER_NONE = 0x00,
|
||||
LV_BORDER_BOTTOM = 0x01,
|
||||
LV_BORDER_TOP = 0x02,
|
||||
LV_BORDER_LEFT = 0x04,
|
||||
LV_BORDER_RIGHT = 0x08,
|
||||
LV_BORDER_FULL = 0x0F,
|
||||
LV_BORDER_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
|
||||
};
|
||||
typedef uint8_t lv_border_part_t;
|
||||
|
||||
/*Shadow types*/
|
||||
enum {
|
||||
LV_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */
|
||||
LV_SHADOW_FULL, /**< Draw shadow on all sides */
|
||||
};
|
||||
typedef uint8_t lv_shadow_type_t;
|
||||
|
||||
/**
|
||||
* Objects in LittlevGL can be assigned a style - which holds information about
|
||||
* how the object should be drawn.
|
||||
*
|
||||
* This allows for easy customization without having to modify the object's design
|
||||
* function.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t glass : 1; /**< 1: Do not inherit this style*/
|
||||
|
||||
/** Object background. */
|
||||
struct
|
||||
{
|
||||
lv_color_t main_color; /**< Object's main background color. */
|
||||
lv_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */
|
||||
lv_coord_t radius; /**< Object's corner radius. You can use #LV_RADIUS_CIRCLE if you want to draw a circle. */
|
||||
lv_opa_t opa; /**< Object's opacity (0-255). */
|
||||
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Border color */
|
||||
lv_coord_t width; /**< Border width */
|
||||
lv_border_part_t part; /**< Which borders to draw */
|
||||
lv_opa_t opa; /**< Border opacity. */
|
||||
} border;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_shadow_type_t type; /**< Which parts of the shadow to draw */
|
||||
} shadow;
|
||||
|
||||
struct
|
||||
{
|
||||
lv_coord_t top;
|
||||
lv_coord_t bottom;
|
||||
lv_coord_t left;
|
||||
lv_coord_t right;
|
||||
lv_coord_t inner;
|
||||
} padding;
|
||||
} body;
|
||||
|
||||
/** Style for text drawn by this object. */
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Text color */
|
||||
lv_color_t sel_color; /**< Text selection background color. */
|
||||
const lv_font_t * font;
|
||||
lv_coord_t letter_space; /**< Space between letters */
|
||||
lv_coord_t line_space; /**< Space between lines (vertical) */
|
||||
lv_opa_t opa; /**< Text opacity */
|
||||
} text;
|
||||
|
||||
/**< Style of images. */
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Color to recolor the image with */
|
||||
lv_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */
|
||||
lv_opa_t opa; /**< Opacity of whole image */
|
||||
} image;
|
||||
|
||||
/**< Style of lines (not borders). */
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_opa_t opa;
|
||||
uint8_t rounded : 1; /**< 1: rounded line endings*/
|
||||
} line;
|
||||
} lv_style_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
/** Data structure for style animations. */
|
||||
typedef struct
|
||||
{
|
||||
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it
|
||||
will be modified too*/
|
||||
lv_style_t style_end;
|
||||
lv_style_t * style_anim;
|
||||
lv_anim_ready_cb_t ready_cb;
|
||||
} lv_style_anim_dsc_t;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the basic styles
|
||||
*/
|
||||
void lv_style_init(void);
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
* @param end end style
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Initialize an animation variable.
|
||||
* E.g.:
|
||||
* lv_anim_t a;
|
||||
* lv_style_anim__init(&a);
|
||||
* lv_style_anim_set_...(&a);
|
||||
* lv_style_anim_create(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_style_anim_init(lv_anim_t * a);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param to_anim pointer to the style to animate
|
||||
* @param start pointer to a style to animate from (start value)
|
||||
* @param end pointer to a style to animate to (end value)
|
||||
*/
|
||||
void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end);
|
||||
|
||||
/**
|
||||
* Set the duration and delay of an animation
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param duration duration of the animation in milliseconds
|
||||
* @param delay delay before the animation in milliseconds
|
||||
*/
|
||||
static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)
|
||||
{
|
||||
lv_anim_set_time(a, duration, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function call when the animation is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param ready_cb a function call when the animation is ready
|
||||
*/
|
||||
static inline void lv_style_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)
|
||||
{
|
||||
lv_style_anim_dsc_t * dsc = (lv_style_anim_dsc_t *)a->var;
|
||||
dsc->ready_cb = ready_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to play back to when the forward direction is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the back direction
|
||||
*/
|
||||
static inline void lv_style_anim_set_playback(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
lv_anim_set_playback(a, wait_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable playback. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_style_anim_clear_playback(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_clear_playback(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to start again when ready.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the animation again
|
||||
*/
|
||||
static inline void lv_style_anim_set_repeat(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
lv_anim_set_repeat(a, wait_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable repeat. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_style_anim_clear_repeat(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_clear_repeat(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation
|
||||
* @param a an initialized 'anim_t' variable. Not required after call.
|
||||
*/
|
||||
static inline void lv_style_anim_create(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_create(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*************************
|
||||
* GLOBAL VARIABLES
|
||||
*************************/
|
||||
extern lv_style_t lv_style_scr;
|
||||
extern lv_style_t lv_style_transp;
|
||||
extern lv_style_t lv_style_transp_fit;
|
||||
extern lv_style_t lv_style_transp_tight;
|
||||
extern lv_style_t lv_style_plain;
|
||||
extern lv_style_t lv_style_plain_color;
|
||||
extern lv_style_t lv_style_pretty;
|
||||
extern lv_style_t lv_style_pretty_color;
|
||||
extern lv_style_t lv_style_btn_rel;
|
||||
extern lv_style_t lv_style_btn_pr;
|
||||
extern lv_style_t lv_style_btn_tgl_rel;
|
||||
extern lv_style_t lv_style_btn_tgl_pr;
|
||||
extern lv_style_t lv_style_btn_ina;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_STYLE_H*/
|
||||
190
extended-setup/components/lvgl/src/lv_draw/lv_draw.c
Normal file
190
extended-setup/components/lvgl/src/lv_draw/lv_draw.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* @file lv_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t draw_buf_size = 0;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Give a buffer with the given to use during drawing.
|
||||
* Be careful to not use the buffer while other processes are using it.
|
||||
* @param size the required size
|
||||
*/
|
||||
void * lv_draw_get_buf(uint32_t size)
|
||||
{
|
||||
if(size <= draw_buf_size) return LV_GC_ROOT(_lv_draw_buf);
|
||||
|
||||
LV_LOG_TRACE("lv_draw_get_buf: allocate");
|
||||
|
||||
draw_buf_size = size;
|
||||
|
||||
if(LV_GC_ROOT(_lv_draw_buf) == NULL) {
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_alloc(size);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_draw_buf), size);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the draw buffer
|
||||
*/
|
||||
void lv_draw_free_buf(void)
|
||||
{
|
||||
if(LV_GC_ROOT(_lv_draw_buf)) {
|
||||
lv_mem_free(LV_GC_ROOT(_lv_draw_buf));
|
||||
LV_GC_ROOT(_lv_draw_buf) = NULL;
|
||||
draw_buf_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/**
|
||||
* Get the opacity of a pixel based it's position in a line segment
|
||||
* @param seg segment length
|
||||
* @param px_id position of of a pixel which opacity should be get [0..seg-1]
|
||||
* @param base_opa the base opacity
|
||||
* @return the opacity of the given pixel
|
||||
*/
|
||||
lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)
|
||||
{
|
||||
/* How to calculate the opacity of pixels on the edges which makes the anti-aliasing?
|
||||
* For example we have a line like this (y = -0.5 * x):
|
||||
*
|
||||
* | _ _
|
||||
* * * |
|
||||
*
|
||||
* Anti-aliased pixels come to the '*' characters
|
||||
* Calculate what percentage of the pixels should be covered if real line (not rasterized) would
|
||||
* be drawn:
|
||||
* 1. A real line should start on (0;0) and end on (2;1)
|
||||
* 2. So the line intersection coordinates on the first pixel: (0;0) (1;0.5) -> 25% covered
|
||||
* pixel in average
|
||||
* 3. For the second pixel: (1;0.5) (2;1) -> 75% covered pixel in average
|
||||
* 4. The equation: (px_id * 2 + 1) / (segment_width * 2)
|
||||
* segment_width: the line segment which is being anti-aliased (was 2 in the
|
||||
* example) px_id: pixel ID from 0 to (segment_width - 1) result: [0..1] coverage of the pixel
|
||||
*/
|
||||
|
||||
/*Accelerate the common segment sizes to avoid division*/
|
||||
static const lv_opa_t seg1[1] = {128};
|
||||
static const lv_opa_t seg2[2] = {64, 192};
|
||||
static const lv_opa_t seg3[3] = {42, 128, 212};
|
||||
static const lv_opa_t seg4[4] = {32, 96, 159, 223};
|
||||
static const lv_opa_t seg5[5] = {26, 76, 128, 178, 230};
|
||||
static const lv_opa_t seg6[6] = {21, 64, 106, 148, 191, 234};
|
||||
static const lv_opa_t seg7[7] = {18, 55, 91, 128, 164, 200, 237};
|
||||
static const lv_opa_t seg8[8] = {16, 48, 80, 112, 143, 175, 207, 239};
|
||||
|
||||
static const lv_opa_t * seg_map[] = {seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8};
|
||||
|
||||
if(seg == 0)
|
||||
return LV_OPA_TRANSP;
|
||||
else if(seg < 8)
|
||||
return (uint32_t)((uint32_t)seg_map[seg - 1][px_id] * base_opa) >> 8;
|
||||
else {
|
||||
return ((px_id * 2 + 1) * base_opa) / (2 * seg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a vertical anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
aa_inv = true;
|
||||
length = -length;
|
||||
}
|
||||
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);
|
||||
if(aa_inv) px_opa = opa - px_opa;
|
||||
lv_draw_px(x, y + i, mask, color, px_opa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a horizontal anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
aa_inv = true;
|
||||
length = -length;
|
||||
}
|
||||
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);
|
||||
if(aa_inv) px_opa = opa - px_opa;
|
||||
lv_draw_px(x + i, y, mask, color, px_opa);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
109
extended-setup/components/lvgl/src/lv_draw/lv_draw.h
Normal file
109
extended-setup/components/lvgl/src/lv_draw/lv_draw.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @file lv_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_H
|
||||
#define LV_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_style.h"
|
||||
#include "../lv_misc/lv_txt.h"
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Give a buffer with the given to use during drawing.
|
||||
* Be careful to not use the buffer while other processes are using it.
|
||||
* @param size the required size
|
||||
*/
|
||||
void * lv_draw_get_buf(uint32_t size);
|
||||
|
||||
/**
|
||||
* Free the draw buffer
|
||||
*/
|
||||
void lv_draw_free_buf(void);
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/**
|
||||
* Get the opacity of a pixel based it's position in a line segment
|
||||
* @param seg segment length
|
||||
* @param px_id position of of a pixel which opacity should be get [0..seg-1]
|
||||
* @param base_opa the base opacity
|
||||
* @return the opacity of the given pixel
|
||||
*/
|
||||
lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa);
|
||||
|
||||
/**
|
||||
* Add a vertical anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Add a horizontal anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* POST INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_basic.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"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_H*/
|
||||
15
extended-setup/components/lvgl/src/lv_draw/lv_draw.mk
Normal file
15
extended-setup/components/lvgl/src/lv_draw/lv_draw.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
CSRCS += lv_draw_basic.c
|
||||
CSRCS += lv_draw.c
|
||||
CSRCS += lv_draw_rect.c
|
||||
CSRCS += lv_draw_label.c
|
||||
CSRCS += lv_draw_line.c
|
||||
CSRCS += lv_draw_img.c
|
||||
CSRCS += lv_draw_arc.c
|
||||
CSRCS += lv_draw_triangle.c
|
||||
CSRCS += lv_img_decoder.c
|
||||
CSRCS += lv_img_cache.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_draw
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_draw
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)lvgl/src/lv_draw"
|
||||
273
extended-setup/components/lvgl/src/lv_draw/lv_draw_arc.c
Normal file
273
extended-setup/components/lvgl/src/lv_draw/lv_draw_arc.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* @file lv_draw_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_arc.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static uint16_t fast_atan2(int x, int y);
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end);
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* 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 style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t thickness = style->line.width;
|
||||
if(thickness > radius) thickness = radius;
|
||||
|
||||
lv_coord_t r_out = radius;
|
||||
lv_coord_t r_in = r_out - thickness;
|
||||
int16_t deg_base;
|
||||
int16_t deg;
|
||||
lv_coord_t x_start[4];
|
||||
lv_coord_t x_end[4];
|
||||
|
||||
lv_color_t color = style->line.color;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
bool (*deg_test)(uint16_t, uint16_t, uint16_t);
|
||||
if(start_angle <= end_angle)
|
||||
deg_test = deg_test_norm;
|
||||
else
|
||||
deg_test = deg_test_inv;
|
||||
|
||||
if(deg_test(270, start_angle, end_angle))
|
||||
hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); // Left Middle
|
||||
if(deg_test(90, start_angle, end_angle))
|
||||
hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); // Right Middle
|
||||
if(deg_test(180, start_angle, end_angle))
|
||||
ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); // Top Middle
|
||||
if(deg_test(0, start_angle, end_angle))
|
||||
ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); // Bottom middle
|
||||
|
||||
uint32_t r_out_sqr = r_out * r_out;
|
||||
uint32_t r_in_sqr = r_in * r_in;
|
||||
int16_t xi;
|
||||
int16_t yi;
|
||||
for(yi = -r_out; yi < 0; yi++) {
|
||||
x_start[0] = LV_COORD_MIN;
|
||||
x_start[1] = LV_COORD_MIN;
|
||||
x_start[2] = LV_COORD_MIN;
|
||||
x_start[3] = LV_COORD_MIN;
|
||||
x_end[0] = LV_COORD_MIN;
|
||||
x_end[1] = LV_COORD_MIN;
|
||||
x_end[2] = LV_COORD_MIN;
|
||||
x_end[3] = LV_COORD_MIN;
|
||||
for(xi = -r_out; xi < 0; xi++) {
|
||||
|
||||
uint32_t r_act_sqr = xi * xi + yi * yi;
|
||||
if(r_act_sqr > r_out_sqr) continue;
|
||||
|
||||
deg_base = fast_atan2(xi, yi) - 180;
|
||||
|
||||
deg = 180 + deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[0] == LV_COORD_MIN) x_start[0] = xi;
|
||||
} else if(x_start[0] != LV_COORD_MIN && x_end[0] == LV_COORD_MIN) {
|
||||
x_end[0] = xi - 1;
|
||||
}
|
||||
|
||||
deg = 360 - deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[1] == LV_COORD_MIN) x_start[1] = xi;
|
||||
} else if(x_start[1] != LV_COORD_MIN && x_end[1] == LV_COORD_MIN) {
|
||||
x_end[1] = xi - 1;
|
||||
}
|
||||
|
||||
deg = 180 - deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[2] == LV_COORD_MIN) x_start[2] = xi;
|
||||
} else if(x_start[2] != LV_COORD_MIN && x_end[2] == LV_COORD_MIN) {
|
||||
x_end[2] = xi - 1;
|
||||
}
|
||||
|
||||
deg = deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[3] == LV_COORD_MIN) x_start[3] = xi;
|
||||
} else if(x_start[3] != LV_COORD_MIN && x_end[3] == LV_COORD_MIN) {
|
||||
x_end[3] = xi - 1;
|
||||
}
|
||||
|
||||
if(r_act_sqr < r_in_sqr)
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
|
||||
if(x_start[0] != LV_COORD_MIN) {
|
||||
if(x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1;
|
||||
hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[1] != LV_COORD_MIN) {
|
||||
if(x_end[1] == LV_COORD_MIN) x_end[1] = xi - 1;
|
||||
hor_line(center_x + x_start[1], center_y - yi, mask, x_end[1] - x_start[1], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[2] != LV_COORD_MIN) {
|
||||
if(x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1;
|
||||
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);
|
||||
}
|
||||
|
||||
if(x_start[3] != LV_COORD_MIN) {
|
||||
if(x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1;
|
||||
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*TODO*/
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t fast_atan2(int x, int y)
|
||||
{
|
||||
// Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com
|
||||
// Converts any XY values including 0 to a degree value that should be
|
||||
// within +/- 1 degree of the accurate value without needing
|
||||
// large slow trig functions like ArcTan() or ArcCos().
|
||||
// NOTE! at least one of the X or Y values must be non-zero!
|
||||
// This is the full version, for all 4 quadrants and will generate
|
||||
// the angle in integer degrees from 0-360.
|
||||
// Any values of X and Y are usable including negative values provided
|
||||
// they are between -1456 and 1456 so the 16bit multiply does not overflow.
|
||||
|
||||
unsigned char negflag;
|
||||
unsigned char tempdegree;
|
||||
unsigned char comp;
|
||||
unsigned int degree; // this will hold the result
|
||||
// signed int x; // these hold the XY vector at the start
|
||||
// signed int y; // (and they will be destroyed)
|
||||
unsigned int ux;
|
||||
unsigned int uy;
|
||||
|
||||
// Save the sign flags then remove signs and get XY as unsigned ints
|
||||
negflag = 0;
|
||||
if(x < 0) {
|
||||
negflag += 0x01; // x flag bit
|
||||
x = (0 - x); // is now +
|
||||
}
|
||||
ux = x; // copy to unsigned var before multiply
|
||||
if(y < 0) {
|
||||
negflag += 0x02; // y flag bit
|
||||
y = (0 - y); // is now +
|
||||
}
|
||||
uy = y; // copy to unsigned var before multiply
|
||||
|
||||
// 1. Calc the scaled "degrees"
|
||||
if(ux > uy) {
|
||||
degree = (uy * 45) / ux; // degree result will be 0-45 range
|
||||
negflag += 0x10; // octant flag bit
|
||||
} else {
|
||||
degree = (ux * 45) / uy; // degree result will be 0-45 range
|
||||
}
|
||||
|
||||
// 2. Compensate for the 4 degree error curve
|
||||
comp = 0;
|
||||
tempdegree = degree; // use an unsigned char for speed!
|
||||
if(tempdegree > 22) { // if top half of range
|
||||
if(tempdegree <= 44) comp++;
|
||||
if(tempdegree <= 41) comp++;
|
||||
if(tempdegree <= 37) comp++;
|
||||
if(tempdegree <= 32) comp++; // max is 4 degrees compensated
|
||||
} else { // else is lower half of range
|
||||
if(tempdegree >= 2) comp++;
|
||||
if(tempdegree >= 6) comp++;
|
||||
if(tempdegree >= 10) comp++;
|
||||
if(tempdegree >= 15) comp++; // max is 4 degrees compensated
|
||||
}
|
||||
degree += comp; // degree is now accurate to +/- 1 degree!
|
||||
|
||||
// Invert degree if it was X>Y octant, makes 0-45 into 90-45
|
||||
if(negflag & 0x10) degree = (90 - degree);
|
||||
|
||||
// 3. Degree is now 0-90 range for this quadrant,
|
||||
// need to invert it for whichever quadrant it was in
|
||||
if(negflag & 0x02) { // if -Y
|
||||
if(negflag & 0x01) // if -Y -X
|
||||
degree = (180 + degree);
|
||||
else // else is -Y +X
|
||||
degree = (180 - degree);
|
||||
} else { // else is +Y
|
||||
if(negflag & 0x01) // if +Y -X
|
||||
degree = (360 - degree);
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x, y + len);
|
||||
|
||||
lv_draw_fill(&area, mask, color, opa);
|
||||
}
|
||||
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x + len, y);
|
||||
|
||||
lv_draw_fill(&area, mask, color, opa);
|
||||
}
|
||||
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start && deg <= end)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start || deg <= end) {
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
52
extended-setup/components/lvgl/src/lv_draw/lv_draw_arc.h
Normal file
52
extended-setup/components/lvgl/src/lv_draw/lv_draw_arc.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file lv_draw_arc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_ARC_H
|
||||
#define LV_DRAW_ARC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* 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 style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_ARC*/
|
||||
707
extended-setup/components/lvgl/src/lv_draw/lv_draw_basic.c
Normal file
707
extended-setup/components/lvgl/src/lv_draw/lv_draw_basic.c
Normal file
@@ -0,0 +1,707 @@
|
||||
/**
|
||||
* @file lv_draw_basic.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lv_draw_basic.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/
|
||||
#define VFILL_HW_ACC_SIZE_LIMIT 50
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Put a pixel in the Virtual Display Buffer
|
||||
* @param x pixel x coordinate
|
||||
* @param y pixel y coordinate
|
||||
* @param mask_p fill only on this mask (truncated to VDB area)
|
||||
* @param color pixel color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
/*Pixel out of the mask*/
|
||||
if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
|
||||
/*Make the coordinates relative to VDB*/
|
||||
x -= vdb->area.x1;
|
||||
y -= vdb->area.y1;
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
|
||||
} else {
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
lv_color_t * vdb_px_p = vdb->buf_act;
|
||||
vdb_px_p += y * vdb_width + x;
|
||||
|
||||
if(scr_transp == false) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
*vdb_px_p = color;
|
||||
} else {
|
||||
*vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);
|
||||
}
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
*vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
* @param mask_p fill only o this mask (truncated to VDB area)
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
lv_area_t res_a;
|
||||
bool union_ok;
|
||||
|
||||
/*Get the union of cord and mask*/
|
||||
/* The mask is already truncated to the vdb size
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
union_ok = lv_area_intersect(&res_a, cords_p, mask_p);
|
||||
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
|
||||
vdb_rel_a.x1 = res_a.x1 - vdb->area.x1;
|
||||
vdb_rel_a.y1 = res_a.y1 - vdb->area.y1;
|
||||
vdb_rel_a.x2 = res_a.x2 - vdb->area.x1;
|
||||
vdb_rel_a.y2 = res_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
/*Move the vdb_tmp to the first row*/
|
||||
vdb_buf_tmp += vdb_width * vdb_rel_a.y1;
|
||||
|
||||
#if LV_USE_GPU
|
||||
static LV_ATTRIBUTE_MEM_ALIGN lv_color_t color_array_tmp[LV_HOR_RES_MAX]; /*Used by 'lv_disp_mem_blend'*/
|
||||
static lv_coord_t last_width = -1;
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&vdb_rel_a);
|
||||
/*Don't use hw. acc. for every small fill (because of the init overhead)*/
|
||||
if(w < VFILL_HW_ACC_SIZE_LIMIT) {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
/*Not opaque fill*/
|
||||
else if(opa == LV_OPA_COVER) {
|
||||
/*Use hw fill if present*/
|
||||
if(disp->driver.gpu_fill_cb) {
|
||||
disp->driver.gpu_fill_cb(&disp->driver, vdb->buf_act, vdb_width, &vdb_rel_a, color);
|
||||
}
|
||||
/*Use hw blend if present and the area is not too small*/
|
||||
else if(lv_area_get_height(&vdb_rel_a) > VFILL_HW_ACC_SIZE_LIMIT && disp->driver.gpu_blend_cb) {
|
||||
/*Fill a one line sized buffer with a color and blend this later*/
|
||||
if(color_array_tmp[0].full != color.full || last_width != w) {
|
||||
uint16_t i;
|
||||
for(i = 0; i < w; i++) {
|
||||
color_array_tmp[i].full = color.full;
|
||||
}
|
||||
last_width = w;
|
||||
}
|
||||
|
||||
/*Blend the filled line to every line VDB line-by-line*/
|
||||
lv_coord_t row;
|
||||
for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
|
||||
}
|
||||
/*Else use sw fill if no better option*/
|
||||
else {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
|
||||
}
|
||||
/*Fill with opacity*/
|
||||
else {
|
||||
/*Use hw blend if present*/
|
||||
if(disp->driver.gpu_blend_cb) {
|
||||
if(color_array_tmp[0].full != color.full || last_width != w) {
|
||||
uint16_t i;
|
||||
for(i = 0; i < w; i++) {
|
||||
color_array_tmp[i].full = color.full;
|
||||
}
|
||||
|
||||
last_width = w;
|
||||
}
|
||||
lv_coord_t row;
|
||||
for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
|
||||
}
|
||||
/*Use sw fill with opa if no better option*/
|
||||
else {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
}
|
||||
#else
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a letter in the Virtual Display Buffer
|
||||
* @param pos_p left-top coordinate of the latter
|
||||
* @param mask_p the letter will be drawn only on this area (truncated to VDB area)
|
||||
* @param font_p pointer to font
|
||||
* @param letter a letter to draw
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
/*clang-format off*/
|
||||
const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
/*clang-format on*/
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
if(font_p == NULL) {
|
||||
LV_LOG_WARN("Font: character's bitmap not found");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_font_glyph_dsc_t g;
|
||||
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
||||
if(g_ret == false) return;
|
||||
|
||||
lv_coord_t pos_x = pos_p->x + g.ofs_x;
|
||||
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
|
||||
|
||||
const uint8_t * bpp_opa_table;
|
||||
uint8_t bitmask_init;
|
||||
uint8_t bitmask;
|
||||
|
||||
switch(g.bpp) {
|
||||
case 1:
|
||||
bpp_opa_table = bpp1_opa_table;
|
||||
bitmask_init = 0x80;
|
||||
break;
|
||||
case 2:
|
||||
bpp_opa_table = bpp2_opa_table;
|
||||
bitmask_init = 0xC0;
|
||||
break;
|
||||
case 4:
|
||||
bpp_opa_table = bpp4_opa_table;
|
||||
bitmask_init = 0xF0;
|
||||
break;
|
||||
case 8:
|
||||
bpp_opa_table = NULL;
|
||||
bitmask_init = 0xFF;
|
||||
break; /*No opa table, pixel value will be used directly*/
|
||||
default: return; /*Invalid bpp. Can't render the letter*/
|
||||
}
|
||||
|
||||
const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);
|
||||
|
||||
if(map_p == NULL) return;
|
||||
|
||||
/*If the letter is completely out of mask don't draw it */
|
||||
if(pos_x + g.box_w < mask_p->x1 || pos_x > mask_p->x2 || pos_y + g.box_h < mask_p->y1 || pos_y > mask_p->y2) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
lv_coord_t col, row;
|
||||
|
||||
uint8_t width_byte_scr = g.box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
|
||||
if(g.box_w & 0x7) width_byte_scr++;
|
||||
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
|
||||
|
||||
/* Calculate the col/row start/end on the map*/
|
||||
lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||
lv_coord_t col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
||||
lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
lv_coord_t row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
|
||||
/*Set a pointer on VDB to the first pixel of the letter*/
|
||||
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
|
||||
|
||||
/*If the letter is partially out of mask the move there on VDB*/
|
||||
vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||
|
||||
/*Move on the map too*/
|
||||
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);
|
||||
map_p += bit_ofs >> 3;
|
||||
|
||||
uint8_t letter_px;
|
||||
lv_opa_t px_opa;
|
||||
uint16_t col_bit;
|
||||
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
|
||||
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
for(row = row_start; row < row_end; row++) {
|
||||
bitmask = bitmask_init >> col_bit;
|
||||
for(col = col_start; col < col_end; col++) {
|
||||
letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
||||
} else if(vdb_buf_tmp->full != color.full) {
|
||||
if(px_opa > LV_OPA_MAX)
|
||||
*vdb_buf_tmp = color;
|
||||
else if(px_opa > LV_OPA_MIN) {
|
||||
if(scr_transp == false) {
|
||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vdb_buf_tmp++;
|
||||
|
||||
if(col_bit < 8 - g.bpp) {
|
||||
col_bit += g.bpp;
|
||||
bitmask = bitmask >> g.bpp;
|
||||
} else {
|
||||
col_bit = 0;
|
||||
bitmask = bitmask_init;
|
||||
map_p++;
|
||||
}
|
||||
}
|
||||
col_bit += ((g.box_w - col_end) + col_start) * g.bpp;
|
||||
|
||||
map_p += (col_bit >> 3);
|
||||
col_bit = col_bit & 0x7;
|
||||
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a color map to the display (image)
|
||||
* @param cords_p coordinates the color map
|
||||
* @param mask_p the map will drawn only on this area (truncated to VDB area)
|
||||
* @param map_p pointer to a lv_color_t array
|
||||
* @param opa opacity of the map
|
||||
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
|
||||
* @param alpha_byte true: extra alpha byte is inserted for every pixel
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,
|
||||
bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa)
|
||||
{
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
lv_area_t masked_a;
|
||||
bool union_ok;
|
||||
|
||||
/*Get the union of map size and mask*/
|
||||
/* The mask is already truncated to the vdb size
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
|
||||
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) return;
|
||||
|
||||
/*The pixel size in byte is different if an alpha byte is added too*/
|
||||
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
|
||||
|
||||
/*If the map starts OUT of the masked area then calc. the first pixel*/
|
||||
lv_coord_t map_width = lv_area_get_width(cords_p);
|
||||
if(cords_p->y1 < masked_a.y1) {
|
||||
map_p += (uint32_t)map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;
|
||||
}
|
||||
if(cords_p->x1 < masked_a.x1) {
|
||||
map_p += (masked_a.x1 - cords_p->x1) * px_size_byte;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
/*Stores coordinates relative to the current VDB*/
|
||||
masked_a.x1 = masked_a.x1 - vdb->area.x1;
|
||||
masked_a.y1 = masked_a.y1 - vdb->area.y1;
|
||||
masked_a.x2 = masked_a.x2 - vdb->area.x1;
|
||||
masked_a.y2 = masked_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
vdb_buf_tmp += (uint32_t)vdb_width * masked_a.y1; /*Move to the first row*/
|
||||
vdb_buf_tmp += (uint32_t)masked_a.x1; /*Move to the first col*/
|
||||
|
||||
lv_coord_t row;
|
||||
lv_coord_t map_useful_w = lv_area_get_width(&masked_a);
|
||||
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
/*The simplest case just copy the pixels into the VDB*/
|
||||
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
|
||||
|
||||
/*Use the custom VDB write function is exists*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
lv_coord_t col;
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_color_t px_color = *((lv_color_t *)&map_p[(uint32_t)col * px_size_byte]);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row,
|
||||
px_color, opa);
|
||||
}
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
}
|
||||
}
|
||||
/*Normal native VDB*/
|
||||
else {
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
#if LV_USE_GPU
|
||||
if(disp->driver.gpu_blend_cb == false) {
|
||||
sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
} else {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
}
|
||||
#else
|
||||
sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
#endif
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*In the other cases every pixel need to be checked one-by-one*/
|
||||
else {
|
||||
|
||||
lv_coord_t col;
|
||||
lv_color_t last_img_px = LV_COLOR_BLACK;
|
||||
lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_opa_t opa_result = opa;
|
||||
uint8_t * px_color_p = (uint8_t *)&map_p[(uint32_t)col * px_size_byte];
|
||||
lv_color_t px_color;
|
||||
|
||||
/*Calculate with the pixel level alpha*/
|
||||
if(alpha_byte) {
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
px_color.full = px_color_p[0];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause
|
||||
* crash*/
|
||||
px_color.full = px_color_p[0] + (px_color_p[1] << 8);
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
#endif
|
||||
lv_opa_t px_opa = *(px_color_p + LV_IMG_PX_SIZE_ALPHA_BYTE - 1);
|
||||
if(px_opa == LV_OPA_TRANSP)
|
||||
continue;
|
||||
else if(px_opa != LV_OPA_COVER)
|
||||
opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;
|
||||
} else {
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
}
|
||||
|
||||
/*Handle chroma key*/
|
||||
if(chroma_key && px_color.full == disp->driver.color_chroma_key.full) continue;
|
||||
|
||||
/*Re-color the pixel if required*/
|
||||
if(recolor_opa != LV_OPA_TRANSP) {
|
||||
if(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for
|
||||
new colors (save the last)*/
|
||||
last_img_px = px_color;
|
||||
recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
}
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,
|
||||
row, recolored_px, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col].full = recolored_px.full;
|
||||
else
|
||||
vdb_buf_tmp[col] = lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);
|
||||
}
|
||||
} else {
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,
|
||||
row, px_color, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col] = px_color;
|
||||
else {
|
||||
if(scr_transp == false) {
|
||||
vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result);
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
vdb_buf_tmp[col] = color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].ch.alpha,
|
||||
px_color, opa_result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Blend pixels to destination memory using opacity
|
||||
* @param dest a memory address. Copy 'src' here.
|
||||
* @param src pointer to pixel map. Copy it to 'dest'.
|
||||
* @param length number of pixels in 'src'
|
||||
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
|
||||
*/
|
||||
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
|
||||
{
|
||||
if(opa == LV_OPA_COVER) {
|
||||
memcpy(dest, src, length * sizeof(lv_color_t));
|
||||
} else {
|
||||
uint32_t col;
|
||||
for(col = 0; col < length; col++) {
|
||||
dest[col] = lv_color_mix(src[col], dest[col], opa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an area with a color
|
||||
* @param mem a memory address. Considered to a rectangular window according to 'mem_area'
|
||||
* @param mem_width width of the 'mem' buffer
|
||||
* @param fill_area coordinates of an area to fill. Relative to 'mem_area'.
|
||||
* @param color fill color
|
||||
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
|
||||
*/
|
||||
static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
/*Set all row in vdb to the given color*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t col;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.set_px_cb) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color, opa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mem += fill_area->y1 * mem_width; /*Go to the first row*/
|
||||
|
||||
/*Run simpler function without opacity*/
|
||||
if(opa == LV_OPA_COVER) {
|
||||
|
||||
/*Fill the first row with 'color'*/
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
mem[col] = color;
|
||||
}
|
||||
|
||||
/*Copy the first row to all other rows*/
|
||||
lv_color_t * mem_first = &mem[fill_area->x1];
|
||||
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
|
||||
mem += mem_width;
|
||||
|
||||
for(row = fill_area->y1 + 1; row <= fill_area->y2; row++) {
|
||||
memcpy(&mem[fill_area->x1], mem_first, copy_size);
|
||||
mem += mem_width;
|
||||
}
|
||||
}
|
||||
/*Calculate with alpha too*/
|
||||
else {
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
lv_color_t bg_tmp = LV_COLOR_BLACK;
|
||||
lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
if(scr_transp == false) {
|
||||
/*If the bg color changed recalculate the result color*/
|
||||
if(mem[col].full != bg_tmp.full) {
|
||||
bg_tmp = mem[col];
|
||||
opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
}
|
||||
|
||||
mem[col] = opa_tmp;
|
||||
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
mem[col] = color_mix_2_alpha(mem[col], mem[col].ch.alpha, color, opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mem += mem_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
/**
|
||||
* Mix two colors. Both color can have alpha value. It requires ARGB888 colors.
|
||||
* @param bg_color background color
|
||||
* @param bg_opa alpha of the background color
|
||||
* @param fg_color foreground color
|
||||
* @param fg_opa alpha of the foreground color
|
||||
* @return the mixed color. the alpha channel (color.alpha) contains the result alpha
|
||||
*/
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa)
|
||||
{
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully transparent*/
|
||||
if(fg_opa > LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {
|
||||
fg_color.ch.alpha = fg_opa;
|
||||
return fg_color;
|
||||
}
|
||||
/*Transparent foreground: use the Background*/
|
||||
else if(fg_opa <= LV_OPA_MIN) {
|
||||
return bg_color;
|
||||
}
|
||||
/*Opaque background: use simple mix*/
|
||||
else if(bg_opa >= LV_OPA_MAX) {
|
||||
return lv_color_mix(fg_color, bg_color, fg_opa);
|
||||
}
|
||||
/*Both colors have alpha. Expensive calculation need to be applied*/
|
||||
else {
|
||||
/*Save the parameters and the result. If they will be asked again don't compute again*/
|
||||
static lv_opa_t fg_opa_save = 0;
|
||||
static lv_opa_t bg_opa_save = 0;
|
||||
static lv_color_t fg_color_save = {{0}};
|
||||
static lv_color_t bg_color_save = {{0}};
|
||||
static lv_color_t c = {{0}};
|
||||
|
||||
if(fg_opa != fg_opa_save || bg_opa != bg_opa_save || fg_color.full != fg_color_save.full ||
|
||||
bg_color.full != bg_color_save.full) {
|
||||
fg_opa_save = fg_opa;
|
||||
bg_opa_save = bg_opa;
|
||||
fg_color_save.full = fg_color.full;
|
||||
bg_color_save.full = bg_color.full;
|
||||
/*Info:
|
||||
* https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
lv_opa_t alpha_res = 255 - ((uint16_t)((uint16_t)(255 - fg_opa) * (255 - bg_opa)) >> 8);
|
||||
if(alpha_res == 0) {
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t)fg_opa * 255) / alpha_res;
|
||||
c = lv_color_mix(fg_color, bg_color, ratio);
|
||||
c.ch.alpha = alpha_res;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
82
extended-setup/components/lvgl/src/lv_draw/lv_draw_basic.h
Normal file
82
extended-setup/components/lvgl/src/lv_draw/lv_draw_basic.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @file lv_draw_basic.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_BASIC_H
|
||||
#define LV_DRAW_BASIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
* @param mask_p fill only o this mask
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a letter in the Virtual Display Buffer
|
||||
* @param pos_p left-top coordinate of the latter
|
||||
* @param mask_p the letter will be drawn only on this area
|
||||
* @param font_p pointer to font
|
||||
* @param letter a letter to draw
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a color map to the display (image)
|
||||
* @param cords_p coordinates the color map
|
||||
* @param mask_p the map will drawn only on this area (truncated to VDB area)
|
||||
* @param map_p pointer to a lv_color_t array
|
||||
* @param opa opacity of the map
|
||||
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
|
||||
* @param alpha_byte true: extra alpha byte is inserted for every pixel
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,
|
||||
bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BASIC_H*/
|
||||
494
extended-setup/components/lvgl/src/lv_draw/lv_draw_img.c
Normal file
494
extended-setup/components/lvgl/src/lv_draw/lv_draw_img.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/**
|
||||
* @file lv_draw_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_img.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* 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 style style of the image
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
if(src == NULL) {
|
||||
LV_LOG_WARN("Image draw: src is NULL");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_res_t res;
|
||||
res = lv_img_draw_core(coords, mask, src, style, opa_scale);
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of an image's pixel
|
||||
* @param dsc an image descriptor
|
||||
* @param x x coordinate of the point to get
|
||||
* @param y x coordinate of the point to get
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows
|
||||
* the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not
|
||||
* used.
|
||||
* @return color of the point
|
||||
*/
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style)
|
||||
{
|
||||
lv_color_t p_color = LV_COLOR_BLACK;
|
||||
if(x >= dsc->header.w) {
|
||||
x = dsc->header.w - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)");
|
||||
} else if(x < 0) {
|
||||
x = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
if(y >= dsc->header.h) {
|
||||
y = dsc->header.h - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)");
|
||||
} else if(y < 0) {
|
||||
y = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED ||
|
||||
dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t));
|
||||
#if LV_COLOR_SIZE == 32
|
||||
p_color.ch.alpha = 0xFF; /*Only the color should be get so use a deafult alpha value*/
|
||||
#endif
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
buf_u8 += 4 * 2;
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 3) * y + x;
|
||||
p_color.full = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {
|
||||
buf_u8 += 4 * 4;
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 2) * y + x;
|
||||
p_color.full = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {
|
||||
buf_u8 += 4 * 16;
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 1) * y + x;
|
||||
p_color.full = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
buf_u8 += 4 * 256;
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
p_color.full = buf_u8[px];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
if(style)
|
||||
p_color = style->image.color;
|
||||
else
|
||||
p_color = LV_COLOR_BLACK;
|
||||
}
|
||||
return p_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha value of an image's pixel
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @return alpha value of the point
|
||||
*/
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
if(x >= dsc->header.w) {
|
||||
x = dsc->header.w - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)");
|
||||
} else if(x < 0) {
|
||||
x = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
if(y >= dsc->header.h) {
|
||||
y = dsc->header.h - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)");
|
||||
} else if(y < 0) {
|
||||
y = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint32_t px = dsc->header.w * y * LV_IMG_PX_SIZE_ALPHA_BYTE + x * LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
return buf_u8[px + LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 3) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);
|
||||
return px_opa ? LV_OPA_TRANSP : LV_OPA_COVER;
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {
|
||||
const uint8_t opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 2) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);
|
||||
return opa_table[px_opa];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {
|
||||
const uint8_t opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 1) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);
|
||||
return opa_table[px_opa];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
return buf_u8[px];
|
||||
}
|
||||
|
||||
return LV_OPA_COVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of a pixel of an image. The alpha channel won't be affected.
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c)
|
||||
{
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&buf_u8[px], &c, px_size);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&buf_u8[px], &c, px_size - 1); /*-1 to not overwrite the alpha value*/
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 2; /*Skip the palette*/
|
||||
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
uint32_t px = (dsc->header.w >> 3) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0x1) << (7 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 4; /*Skip the palette*/
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 2) * y + x;
|
||||
|
||||
buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0x3) << (6 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 16; /*Skip the palette*/
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 1) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0xF) << (4 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 256; /*Skip the palette*/
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
buf_u8[px] = c.full;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha value of a pixel of an image. The color won't be affected
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param opa the desired opacity
|
||||
*/
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa)
|
||||
{
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
buf_u8[px + px_size - 1] = opa;
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {
|
||||
opa = opa >> 7; /*opa -> [0,1]*/
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
uint32_t px = (dsc->header.w >> 3) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0x1) << (7 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {
|
||||
opa = opa >> 6; /*opa -> [0,3]*/
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
uint32_t px = (dsc->header.w >> 2) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0x3) << (6 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {
|
||||
opa = opa >> 4; /*opa -> [0,15]*/
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
uint32_t px = (dsc->header.w >> 1) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0xF) << (4 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
buf_u8[px] = opa;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param id the palette color to set:
|
||||
* - for `LV_IMG_CF_INDEXED1`: 0..1
|
||||
* - for `LV_IMG_CF_INDEXED2`: 0..3
|
||||
* - for `LV_IMG_CF_INDEXED4`: 0..15
|
||||
* - for `LV_IMG_CF_INDEXED8`: 0..255
|
||||
* @param c the color to set
|
||||
*/
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c)
|
||||
{
|
||||
if((dsc->header.cf == LV_IMG_CF_ALPHA_1BIT && id > 1) || (dsc->header.cf == LV_IMG_CF_ALPHA_2BIT && id > 3) ||
|
||||
(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT && id > 15) || (dsc->header.cf == LV_IMG_CF_ALPHA_8BIT)) {
|
||||
LV_LOG_WARN("lv_img_buf_set_px_alpha: invalid 'id'");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(c);
|
||||
uint8_t * buf = (uint8_t *)dsc->data;
|
||||
memcpy(&buf[id * sizeof(c32)], &c32, sizeof(c32));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_color_format_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_color_format_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:
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT: 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_color_format_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_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 design 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;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
lv_area_t mask_com; /*Common area of mask and coords*/
|
||||
bool union_ok;
|
||||
union_ok = lv_area_intersect(&mask_com, mask, coords);
|
||||
if(union_ok == false) {
|
||||
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
|
||||
successfully.*/
|
||||
}
|
||||
|
||||
lv_opa_t opa =
|
||||
opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;
|
||||
|
||||
lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style);
|
||||
|
||||
if(cdsc == NULL) return LV_RES_INV;
|
||||
|
||||
bool chroma_keyed = lv_img_color_format_is_chroma_keyed(cdsc->dec_dsc.header.cf);
|
||||
bool alpha_byte = lv_img_color_format_has_alpha(cdsc->dec_dsc.header.cf);
|
||||
|
||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1,
|
||||
-1, NULL);
|
||||
}
|
||||
/* The decoder open could open the image and gave the entire uncompressed image.
|
||||
* Just draw it!*/
|
||||
else if(cdsc->dec_dsc.img_data) {
|
||||
lv_draw_map(coords, mask, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color,
|
||||
style->image.intense);
|
||||
}
|
||||
/* The whole uncompressed image is not available. Try to read it line-by-line*/
|
||||
else {
|
||||
lv_coord_t width = lv_area_get_width(&mask_com);
|
||||
|
||||
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * ((LV_COLOR_DEPTH >> 3) + 1)); /*+1 because of the possible alpha byte*/
|
||||
|
||||
lv_area_t line;
|
||||
lv_area_copy(&line, &mask_com);
|
||||
lv_area_set_height(&line, 1);
|
||||
lv_coord_t x = mask_com.x1 - coords->x1;
|
||||
lv_coord_t y = mask_com.y1 - coords->y1;
|
||||
lv_coord_t row;
|
||||
lv_res_t read_res;
|
||||
for(row = mask_com.y1; row <= mask_com.y2; row++) {
|
||||
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");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
lv_draw_map(&line, mask, buf, opa, chroma_keyed, alpha_byte, style->image.color, style->image.intense);
|
||||
line.y1++;
|
||||
line.y2++;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
131
extended-setup/components/lvgl/src/lv_draw/lv_draw_img.h
Normal file
131
extended-setup/components/lvgl/src/lv_draw/lv_draw_img.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @file lv_draw_img.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_IMG_H
|
||||
#define LV_DRAW_IMG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* 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 style style of the image
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* 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 color of an image's pixel
|
||||
* @param dsc an image descriptor
|
||||
* @param x x coordinate of the point to get
|
||||
* @param y x coordinate of the point to get
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows
|
||||
* the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not
|
||||
* used.
|
||||
* @return color of the point
|
||||
*/
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style);
|
||||
/**
|
||||
* Get the alpha value of an image's pixel
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @return alpha value of the point
|
||||
*/
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the color of a pixel of an image. The alpha channel won't be affected.
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);
|
||||
|
||||
/**
|
||||
* Set the alpha value of a pixel of an image. The color won't be affected
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param opa the desired opacity
|
||||
*/
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param id the palette color to set:
|
||||
* - for `LV_IMG_CF_INDEXED1`: 0..1
|
||||
* - for `LV_IMG_CF_INDEXED2`: 0..3
|
||||
* - for `LV_IMG_CF_INDEXED4`: 0..15
|
||||
* - for `LV_IMG_CF_INDEXED8`: 0..255
|
||||
* @param c the color to set
|
||||
*/
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c);
|
||||
|
||||
/**
|
||||
* 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_color_format_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_color_format_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_color_format_has_alpha(lv_img_cf_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
||||
283
extended-setup/components/lvgl/src/lv_draw/lv_draw_label.c
Normal file
283
extended-setup/components/lvgl/src/lv_draw/lv_draw_label.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* @file lv_draw_label.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_label.h"
|
||||
#include "../lv_misc/lv_math.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
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write a text
|
||||
* @param coords coordinates of the label
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param txt 0 terminated text to write
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,
|
||||
lv_draw_label_hint_t * hint)
|
||||
{
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t w;
|
||||
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
||||
/*Normally use the label's width as width*/
|
||||
w = lv_area_get_width(coords);
|
||||
} else {
|
||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
|
||||
flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
lv_coord_t line_height = lv_font_get_line_height(font) + style->text.line_space;
|
||||
|
||||
/*Init variables for the first line*/
|
||||
lv_coord_t line_width = 0;
|
||||
lv_point_t pos;
|
||||
pos.x = coords->x1;
|
||||
pos.y = coords->y1;
|
||||
|
||||
lv_coord_t x_ofs = 0;
|
||||
lv_coord_t y_ofs = 0;
|
||||
if(offset != NULL) {
|
||||
x_ofs = offset->x;
|
||||
y_ofs = offset->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) {
|
||||
/*If the label changed too much recalculate the hint.*/
|
||||
if(LV_MATH_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, style->text.letter_space, w, flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
while(pos.y + line_height < mask->y1) {
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, 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(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
||||
|
||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||
uint32_t i;
|
||||
uint16_t par_start = 0;
|
||||
lv_color_t recolor;
|
||||
lv_coord_t letter_w;
|
||||
lv_style_t sel_style;
|
||||
lv_style_copy(&sel_style, &lv_style_plain_color);
|
||||
sel_style.body.main_color = sel_style.body.grad_color = style->text.sel_color;
|
||||
|
||||
/*Write out all lines*/
|
||||
while(txt[line_start] != '\0') {
|
||||
if(offset != NULL) {
|
||||
pos.x += x_ofs;
|
||||
}
|
||||
/*Write all letter of a line*/
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
i = line_start;
|
||||
uint32_t letter;
|
||||
uint32_t letter_next;
|
||||
while(i < line_end) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter_next = lv_txt_encoded_next(&txt[i], NULL);
|
||||
|
||||
/*Handle the re-color command*/
|
||||
if((flag & LV_TXT_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];
|
||||
memcpy(buf, &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 = style->text.color.full;
|
||||
}
|
||||
cmd_state = CMD_STATE_IN; /*After the parameter the text is in the command*/
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lv_color_t color = style->text.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) {
|
||||
int char_ind = lv_encoded_get_char_id(txt, i);
|
||||
/*Do not draw the rectangle on the character at `sel_start`.*/
|
||||
if(char_ind > sel_start && char_ind <= sel_end) {
|
||||
lv_area_t sel_coords;
|
||||
sel_coords.x1 = pos.x;
|
||||
sel_coords.y1 = pos.y;
|
||||
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
||||
sel_coords.y2 = pos.y + line_height - 1;
|
||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||
}
|
||||
}
|
||||
lv_draw_letter(&pos, mask, font, letter, color, opa);
|
||||
|
||||
if(letter_w > 0) {
|
||||
pos.x += letter_w + style->text.letter_space;
|
||||
}
|
||||
}
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||
|
||||
pos.x = coords->x1;
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
/*Go the next line position*/
|
||||
pos.y += line_height;
|
||||
|
||||
if(pos.y > mask->y2) return;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* 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;
|
||||
}
|
||||
71
extended-setup/components/lvgl/src/lv_draw/lv_draw_label.h
Normal file
71
extended-setup/components/lvgl/src/lv_draw/lv_draw_label.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file lv_draw_label.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LABEL_H
|
||||
#define LV_DRAW_LABEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** 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 {
|
||||
/** 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;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write a text
|
||||
* @param coords coordinates of the label
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param txt 0 terminated text to write
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,
|
||||
lv_draw_label_hint_t * hint);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LABEL_H*/
|
||||
636
extended-setup/components/lvgl/src/lv_draw/lv_draw_line.c
Normal file
636
extended-setup/components/lvgl/src/lv_draw/lv_draw_line.c
Normal file
@@ -0,0 +1,636 @@
|
||||
/**
|
||||
* @file lv_draw_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_point_t p_act;
|
||||
lv_coord_t dx;
|
||||
lv_coord_t sx; /*-1: x1 < x2; 1: x2 >= x1*/
|
||||
lv_coord_t dy;
|
||||
lv_coord_t sy; /*-1: y1 < y2; 1: y2 >= y1*/
|
||||
lv_coord_t err;
|
||||
lv_coord_t e2;
|
||||
bool hor; /*Rather horizontal or vertical*/
|
||||
} line_draw_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t width;
|
||||
lv_coord_t width_1;
|
||||
lv_coord_t width_half;
|
||||
} line_width_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2);
|
||||
static bool line_next(line_draw_t * line);
|
||||
static bool line_next_y(line_draw_t * line);
|
||||
static bool line_next_x(line_draw_t * line);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
if(style->line.width == 0) return;
|
||||
if(point1->x == point2->x && point1->y == point2->y) return;
|
||||
|
||||
/*Return if the points are out of the mask*/
|
||||
if(point1->x < mask->x1 - style->line.width && point2->x < mask->x1 - style->line.width) return;
|
||||
if(point1->x > mask->x2 + style->line.width && point2->x > mask->x2 + style->line.width) return;
|
||||
if(point1->y < mask->y1 - style->line.width && point2->y < mask->y1 - style->line.width) return;
|
||||
if(point1->y > mask->y2 + style->line.width && point2->y > mask->y2 + style->line.width) return;
|
||||
|
||||
line_draw_t main_line;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
|
||||
/*If the line if rather vertical then be sure y1 < y2 else x1 < x2*/
|
||||
|
||||
if(LV_MATH_ABS(point1->x - point2->x) > LV_MATH_ABS(point1->y - point2->y)) {
|
||||
|
||||
/*Steps less in y then x -> rather horizontal*/
|
||||
if(point1->x < point2->x) {
|
||||
p1.x = point1->x;
|
||||
p1.y = point1->y;
|
||||
p2.x = point2->x;
|
||||
p2.y = point2->y;
|
||||
} else {
|
||||
p1.x = point2->x;
|
||||
p1.y = point2->y;
|
||||
p2.x = point1->x;
|
||||
p2.y = point1->y;
|
||||
}
|
||||
} else {
|
||||
/*Steps less in x then y -> rather vertical*/
|
||||
if(point1->y < point2->y) {
|
||||
p1.x = point1->x;
|
||||
p1.y = point1->y;
|
||||
p2.x = point2->x;
|
||||
p2.y = point2->y;
|
||||
} else {
|
||||
p1.x = point2->x;
|
||||
p1.y = point2->y;
|
||||
p2.x = point1->x;
|
||||
p2.y = point1->y;
|
||||
}
|
||||
}
|
||||
|
||||
line_init(&main_line, &p1, &p2);
|
||||
|
||||
/*Special case draw a horizontal line*/
|
||||
if(main_line.p1.y == main_line.p2.y) {
|
||||
line_draw_hor(&main_line, mask, style, opa_scale);
|
||||
}
|
||||
/*Special case draw a vertical line*/
|
||||
else if(main_line.p1.x == main_line.p2.x) {
|
||||
line_draw_ver(&main_line, mask, style, opa_scale);
|
||||
}
|
||||
/*Arbitrary skew line*/
|
||||
else {
|
||||
bool dir_ori = false;
|
||||
#if LV_ANTIALIAS
|
||||
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
|
||||
if(aa) {
|
||||
lv_point_t p_tmp;
|
||||
|
||||
if(main_line.hor) {
|
||||
if(main_line.p1.y < main_line.p2.y) {
|
||||
dir_ori = true;
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y - 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
} else if(main_line.p1.y > main_line.p2.y) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y + 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
}
|
||||
} else {
|
||||
if(main_line.p1.x < main_line.p2.x) {
|
||||
dir_ori = true;
|
||||
p_tmp.x = main_line.p2.x - 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
} else if(main_line.p1.x > main_line.p2.x) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x + 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
line_draw_skew(&main_line, dir_ori, mask, style, opa_scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x;
|
||||
act_area.x2 = main_line->p2.x;
|
||||
act_area.y1 = main_line->p1.y - width_half - width_1;
|
||||
act_area.y2 = main_line->p2.y + width_half;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x - width_half;
|
||||
act_area.x2 = main_line->p2.x + width_half + width_1;
|
||||
act_area.y1 = main_line->p1.y;
|
||||
act_area.y2 = main_line->p2.y;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
#if LV_ANTIALIAS
|
||||
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
|
||||
#endif
|
||||
lv_point_t vect_main, vect_norm;
|
||||
vect_main.x = main_line->p2.x - main_line->p1.x;
|
||||
vect_main.y = main_line->p2.y - main_line->p1.y;
|
||||
|
||||
if(main_line->hor) {
|
||||
if(main_line->p1.y < main_line->p2.y + dir_ori) {
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = vect_main.y;
|
||||
vect_norm.y = -vect_main.x;
|
||||
}
|
||||
} else {
|
||||
if(main_line->p1.x < main_line->p2.x + dir_ori) {
|
||||
vect_norm.x = vect_main.y;
|
||||
vect_norm.y = -vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case of a short but tick line the perpendicular ending is longer then the real line.
|
||||
* it would break the calculations so make the normal vector larger*/
|
||||
vect_norm.x = vect_norm.x << 4;
|
||||
vect_norm.y = vect_norm.y << 4;
|
||||
|
||||
lv_coord_t width;
|
||||
width = style->line.width;
|
||||
|
||||
/* The pattern stores the points of the line ending. It has the good direction and length.
|
||||
* The worth case is the 45° line where pattern can have 1.41 x `width` points*/
|
||||
|
||||
lv_point_t * pattern = lv_draw_get_buf(width * 2 * sizeof(lv_point_t));
|
||||
lv_coord_t i = 0;
|
||||
|
||||
/*Create a perpendicular pattern (a small line)*/
|
||||
if(width != 0) {
|
||||
line_draw_t pattern_line;
|
||||
lv_point_t p0 = {0, 0};
|
||||
line_init(&pattern_line, &p0, &vect_norm);
|
||||
|
||||
uint32_t width_sqr = width * width;
|
||||
/* Run for a lot of times. Meanwhile the real width will be determined as well */
|
||||
for(i = 0; i < (lv_coord_t)sizeof(pattern); i++) {
|
||||
pattern[i].x = pattern_line.p_act.x;
|
||||
pattern[i].y = pattern_line.p_act.y;
|
||||
|
||||
/*Finish the pattern line if it's length equal to the desired width (Use Pythagoras
|
||||
* theorem)*/
|
||||
uint32_t sqr = pattern_line.p_act.x * pattern_line.p_act.x + pattern_line.p_act.y * pattern_line.p_act.y;
|
||||
if(sqr >= width_sqr) {
|
||||
width = i;
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) width--;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
line_next(&pattern_line);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
lv_coord_t aa_last_corner;
|
||||
lv_coord_t width_safe = width;
|
||||
if(aa) {
|
||||
if(width == 0) width_safe = 1;
|
||||
|
||||
aa_last_corner = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_coord_t x_center_ofs = 0;
|
||||
lv_coord_t y_center_ofs = 0;
|
||||
|
||||
if(width != 0) {
|
||||
x_center_ofs = pattern[width - 1].x / 2;
|
||||
y_center_ofs = pattern[width - 1].y / 2;
|
||||
} else {
|
||||
if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y--;
|
||||
if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x--;
|
||||
}
|
||||
|
||||
/* Make the coordinates relative to the center */
|
||||
for(i = 0; i < width; i++) {
|
||||
pattern[i].x -= x_center_ofs;
|
||||
pattern[i].y -= y_center_ofs;
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
if(i != 0) {
|
||||
if(main_line->hor) {
|
||||
if(pattern[i - 1].x != pattern[i].x) {
|
||||
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
} else {
|
||||
if(pattern[i - 1].y != pattern[i].y) {
|
||||
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*Add the last part of anti-aliasing for the perpendicular ending*/
|
||||
if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/
|
||||
if(main_line->hor) {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w, seg_w + main_line->sy, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w, -(seg_w + main_line->sy), mask,
|
||||
style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y, seg_w + main_line->sy, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y, -(seg_w + main_line->sy), mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
} else {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,
|
||||
style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/*Shift the anti aliasing on the edges (-1, 1 or 0 (zero only in case width == 0))*/
|
||||
lv_coord_t aa_shift1 = 0;
|
||||
lv_coord_t aa_shift2 = 0;
|
||||
if(aa) {
|
||||
if(main_line->hor == false) {
|
||||
if(main_line->sx < 0) {
|
||||
aa_shift1 = -1;
|
||||
aa_shift2 = width == 0 ? 0 : aa_shift1;
|
||||
} else {
|
||||
aa_shift2 = 1;
|
||||
aa_shift1 = width == 0 ? 0 : aa_shift2;
|
||||
}
|
||||
} else {
|
||||
if(main_line->sy < 0) {
|
||||
aa_shift1 = -1;
|
||||
aa_shift2 = width == 0 ? 0 : aa_shift1;
|
||||
} else {
|
||||
aa_shift2 = 1;
|
||||
aa_shift1 = width == 0 ? 0 : aa_shift2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
volatile lv_point_t prev_p;
|
||||
prev_p.x = main_line->p1.x;
|
||||
prev_p.y = main_line->p1.y;
|
||||
lv_area_t draw_area;
|
||||
bool first_run = true;
|
||||
|
||||
if(main_line->hor) {
|
||||
while(line_next_y(main_line)) {
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x - 1;
|
||||
draw_area.y2 = draw_area.y1;
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x,
|
||||
prev_p.y + pattern[width_safe - 1].y + aa_shift2, main_line->p_act.x - prev_p.x,
|
||||
mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
first_run = false;
|
||||
|
||||
prev_p.x = main_line->p_act.x;
|
||||
prev_p.y = main_line->p_act.y;
|
||||
}
|
||||
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x;
|
||||
draw_area.y2 = draw_area.y1;
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*Rather a vertical line*/
|
||||
else {
|
||||
|
||||
while(line_next_x(main_line)) {
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1;
|
||||
draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2,
|
||||
prev_p.y + pattern[width_safe - 1].y, main_line->p_act.y - prev_p.y, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
first_run = false;
|
||||
|
||||
prev_p.x = main_line->p_act.x;
|
||||
prev_p.y = main_line->p_act.y;
|
||||
}
|
||||
|
||||
/*Draw the last part*/
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1;
|
||||
draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2)
|
||||
{
|
||||
line->p1.x = p1->x;
|
||||
line->p1.y = p1->y;
|
||||
line->p2.x = p2->x;
|
||||
line->p2.y = p2->y;
|
||||
|
||||
line->dx = LV_MATH_ABS(line->p2.x - line->p1.x);
|
||||
line->sx = line->p1.x < line->p2.x ? 1 : -1;
|
||||
line->dy = LV_MATH_ABS(line->p2.y - line->p1.y);
|
||||
line->sy = line->p1.y < line->p2.y ? 1 : -1;
|
||||
line->err = (line->dx > line->dy ? line->dx : -line->dy) / 2;
|
||||
line->e2 = 0;
|
||||
line->hor = line->dx > line->dy ? true : false; /*Rather horizontal or vertical*/
|
||||
|
||||
line->p_act.x = line->p1.x;
|
||||
line->p_act.y = line->p1.y;
|
||||
}
|
||||
|
||||
static bool line_next(line_draw_t * line)
|
||||
{
|
||||
if(line->p_act.x == line->p2.x && line->p_act.y == line->p2.y) return false;
|
||||
line->e2 = line->err;
|
||||
if(line->e2 > -line->dx) {
|
||||
line->err -= line->dy;
|
||||
line->p_act.x += line->sx;
|
||||
}
|
||||
if(line->e2 < line->dy) {
|
||||
line->err += line->dx;
|
||||
line->p_act.y += line->sy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate until step one in y direction.
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
static bool line_next_y(line_draw_t * line)
|
||||
{
|
||||
lv_coord_t last_y = line->p_act.y;
|
||||
|
||||
do {
|
||||
if(!line_next(line)) return false;
|
||||
} while(last_y == line->p_act.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate until step one in x direction.
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
static bool line_next_x(line_draw_t * line)
|
||||
{
|
||||
lv_coord_t last_x = line->p_act.x;
|
||||
|
||||
do {
|
||||
if(!line_next(line)) return false;
|
||||
} while(last_x == line->p_act.x);
|
||||
|
||||
return true;
|
||||
}
|
||||
48
extended-setup/components/lvgl/src/lv_draw/lv_draw_line.h
Normal file
48
extended-setup/components/lvgl/src/lv_draw/lv_draw_line.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file lv_draw_line.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LINE_H
|
||||
#define LV_DRAW_LINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LINE_H*/
|
||||
1521
extended-setup/components/lvgl/src/lv_draw/lv_draw_rect.c
Normal file
1521
extended-setup/components/lvgl/src/lv_draw/lv_draw_rect.c
Normal file
File diff suppressed because it is too large
Load Diff
47
extended-setup/components/lvgl/src/lv_draw/lv_draw_rect.h
Normal file
47
extended-setup/components/lvgl/src/lv_draw/lv_draw_rect.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file lv_draw_rect.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_RECT_H
|
||||
#define LV_DRAW_RECT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
* @param coords the coordinates of the rectangle
|
||||
* @param mask the rectangle will be drawn only in this mask
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_RECT_H*/
|
||||
344
extended-setup/components/lvgl/src/lv_draw/lv_draw_triangle.c
Normal file
344
extended-setup/components/lvgl/src/lv_draw/lv_draw_triangle.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_triangle.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);
|
||||
void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);
|
||||
static void point_swap(lv_point_t * p1, lv_point_t * p2);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param points pointer to an array with 3 points
|
||||
* @param mask the triangle will be drawn only in this mask
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
/*Return is the triangle is degenerated*/
|
||||
if(points[0].x == points[1].x && points[0].y == points[1].y) return;
|
||||
if(points[1].x == points[2].x && points[1].y == points[2].y) return;
|
||||
if(points[0].x == points[2].x && points[0].y == points[2].y) return;
|
||||
|
||||
if(points[0].x == points[1].x && points[1].x == points[2].x) return;
|
||||
if(points[0].y == points[1].y && points[1].y == points[2].y) return;
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
/*Is the triangle flat or tall?*/
|
||||
lv_coord_t x_min = LV_MATH_MIN(LV_MATH_MIN(points[0].x, points[1].x), points[2].x);
|
||||
lv_coord_t x_max = LV_MATH_MAX(LV_MATH_MAX(points[0].x, points[1].x), points[2].x);
|
||||
lv_coord_t y_min = LV_MATH_MIN(LV_MATH_MIN(points[0].y, points[1].y), points[2].y);
|
||||
lv_coord_t y_max = LV_MATH_MAX(LV_MATH_MAX(points[0].y, points[1].y), points[2].y);
|
||||
|
||||
/* Draw the tall rectangles from vertical lines
|
||||
* and from the flat triangles from horizontal lines
|
||||
* to minimize the number of lines.
|
||||
* Some pixels are overdrawn on the common edges of the triangles
|
||||
* so use it only if the triangle has no opacity*/
|
||||
|
||||
/* Draw from horizontal lines*/
|
||||
if(x_max - x_min < y_max - y_min) {
|
||||
tri_draw_tall(points, mask, style, opa);
|
||||
}
|
||||
/*Else flat so draw from vertical lines*/
|
||||
else {
|
||||
tri_draw_flat(points, mask, style, opa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon from triangles. Only convex polygons are supported
|
||||
* @param points an array of points
|
||||
* @param point_cnt number of points
|
||||
* @param mask polygon will be drawn only in this mask
|
||||
* @param style style of the polygon
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
if(point_cnt < 3) return;
|
||||
if(points == NULL) return;
|
||||
|
||||
uint32_t i;
|
||||
lv_point_t tri[3];
|
||||
tri[0].x = points[0].x;
|
||||
tri[0].y = points[0].y;
|
||||
for(i = 0; i < point_cnt - 1; i++) {
|
||||
tri[1].x = points[i].x;
|
||||
tri[1].y = points[i].y;
|
||||
tri[2].x = points[i + 1].x;
|
||||
tri[2].y = points[i + 1].y;
|
||||
lv_draw_triangle(tri, mask, style, opa_scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)
|
||||
{
|
||||
/*Return if the points are out of the mask*/
|
||||
if(points[0].x < mask->x1 && points[1].x < mask->x1 && points[2].x < mask->x1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].x > mask->x2 && points[1].x > mask->x2 && points[2].x > mask->x2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].y < mask->y1 && points[1].y < mask->y1 && points[2].y < mask->y1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].y > mask->y2 && points[1].y > mask->y2 && points[2].y > mask->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_point_t tri[3];
|
||||
|
||||
memcpy(tri, points, sizeof(tri));
|
||||
|
||||
/*Sort the vertices according to their y coordinate (0: y max, 1: y mid, 2:y min)*/
|
||||
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
|
||||
if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]);
|
||||
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
|
||||
|
||||
/*Draw the triangle*/
|
||||
lv_point_t edge1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
lv_coord_t err_tmp1;
|
||||
|
||||
lv_point_t edge2;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
|
||||
lv_coord_t err_tmp2;
|
||||
|
||||
lv_coord_t y1_tmp;
|
||||
lv_coord_t y2_tmp;
|
||||
|
||||
edge1.x = tri[0].x;
|
||||
edge1.y = tri[0].y;
|
||||
edge2.x = tri[0].x;
|
||||
edge2.y = tri[0].y;
|
||||
lv_area_t act_area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
while(1) {
|
||||
act_area.x1 = edge1.x;
|
||||
act_area.x2 = edge2.x;
|
||||
act_area.y1 = edge1.y;
|
||||
act_area.y2 = edge2.y;
|
||||
|
||||
/* Get the area of a line.
|
||||
* Adjust it a little bit to perfectly match (no redrawn pixels) with the adjacent triangles*/
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2) + 1;
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2) - 1;
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->body.main_color, opa);
|
||||
|
||||
/*Calc. the next point of edge1*/
|
||||
y1_tmp = edge1.y;
|
||||
do {
|
||||
if(edge1.x == tri[1].x && edge1.y == tri[1].y) {
|
||||
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
} else if(edge1.x == tri[2].x && edge1.y == tri[2].y) {
|
||||
return;
|
||||
}
|
||||
err_tmp1 = err1;
|
||||
if(err_tmp1 > -dx1) {
|
||||
err1 -= dy1;
|
||||
edge1.x += sx1;
|
||||
}
|
||||
if(err_tmp1 < dy1) {
|
||||
err1 += dx1;
|
||||
edge1.y += sy1;
|
||||
}
|
||||
} while(edge1.y == y1_tmp);
|
||||
|
||||
/*Calc. the next point of edge2*/
|
||||
y2_tmp = edge2.y;
|
||||
do {
|
||||
if(edge2.x == tri[2].x && edge2.y == tri[2].y) return;
|
||||
err_tmp2 = err2;
|
||||
if(err_tmp2 > -dx2) {
|
||||
err2 -= dy2;
|
||||
edge2.x += sx2;
|
||||
}
|
||||
if(err_tmp2 < dy2) {
|
||||
err2 += dx2;
|
||||
edge2.y += sy2;
|
||||
}
|
||||
} while(edge2.y == y2_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)
|
||||
{
|
||||
/*
|
||||
* Better to draw from vertical lines
|
||||
* |\
|
||||
* | |
|
||||
* | |
|
||||
* | \
|
||||
* | |
|
||||
* |___|
|
||||
*/
|
||||
|
||||
lv_point_t tri[3];
|
||||
|
||||
memcpy(tri, points, sizeof(tri));
|
||||
|
||||
/*Sort the vertices according to their x coordinate (0: x max, 1: x mid, 2:x min)*/
|
||||
if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);
|
||||
if(tri[2].x < tri[1].x) point_swap(&tri[2], &tri[1]);
|
||||
if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);
|
||||
|
||||
/*Draw the triangle*/
|
||||
lv_point_t edge1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
lv_coord_t err_tmp1;
|
||||
|
||||
lv_point_t edge2;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
|
||||
lv_coord_t err_tmp2;
|
||||
|
||||
lv_coord_t x1_tmp;
|
||||
lv_coord_t x2_tmp;
|
||||
|
||||
edge1.x = tri[0].x;
|
||||
edge1.y = tri[0].y;
|
||||
edge2.x = tri[0].x;
|
||||
edge2.y = tri[0].y;
|
||||
lv_area_t act_area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
while(1) {
|
||||
act_area.x1 = edge1.x;
|
||||
act_area.x2 = edge2.x;
|
||||
act_area.y1 = edge1.y;
|
||||
act_area.y2 = edge2.y;
|
||||
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->body.main_color, opa);
|
||||
|
||||
/*Calc. the next point of edge1*/
|
||||
x1_tmp = edge1.x;
|
||||
do {
|
||||
if(edge1.y == tri[1].y && edge1.x == tri[1].x) {
|
||||
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
} else if(edge1.y == tri[2].y && edge1.x == tri[2].x) {
|
||||
return;
|
||||
}
|
||||
err_tmp1 = err1;
|
||||
if(err_tmp1 > -dx1) {
|
||||
err1 -= dy1;
|
||||
edge1.x += sx1;
|
||||
}
|
||||
if(err_tmp1 < dy1) {
|
||||
err1 += dx1;
|
||||
edge1.y += sy1;
|
||||
}
|
||||
} while(edge1.x == x1_tmp);
|
||||
|
||||
/*Calc. the next point of edge2*/
|
||||
x2_tmp = edge2.x;
|
||||
do {
|
||||
if(edge2.y == tri[2].y && edge2.x == tri[2].x) {
|
||||
return;
|
||||
}
|
||||
|
||||
err_tmp2 = err2;
|
||||
if(err_tmp2 > -dx2) {
|
||||
err2 -= dy2;
|
||||
edge2.x += sx2;
|
||||
}
|
||||
if(err_tmp2 < dy2) {
|
||||
err2 += dx2;
|
||||
edge2.y += sy2;
|
||||
}
|
||||
} while(edge2.x == x2_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap two points
|
||||
* p1 pointer to the first point
|
||||
* p2 pointer to the second point
|
||||
*/
|
||||
static void point_swap(lv_point_t * p1, lv_point_t * p2)
|
||||
{
|
||||
lv_point_t tmp;
|
||||
tmp.x = p1->x;
|
||||
tmp.y = p1->y;
|
||||
|
||||
p1->x = p2->x;
|
||||
p1->y = p2->y;
|
||||
|
||||
p2->x = tmp.x;
|
||||
p2->y = tmp.y;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_TRIANGLE_H
|
||||
#define LV_DRAW_TRIANGLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param points pointer to an array with 3 points
|
||||
* @param mask the triangle will be drawn only in this mask
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* Draw a polygon from triangles. Only convex polygons are supported
|
||||
* @param points an array of points
|
||||
* @param point_cnt number of points
|
||||
* @param mask polygon will be drawn only in this mask
|
||||
* @param style style of the polygon
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_TRIANGLE_H*/
|
||||
195
extended-setup/components/lvgl/src/lv_draw/lv_img_cache.c
Normal file
195
extended-setup/components/lvgl/src/lv_draw/lv_img_cache.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @file lv_img_cache.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_cache.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Decrement life with this value in every open*/
|
||||
#define LV_IMG_CACHE_AGING 1
|
||||
|
||||
/*Boost life by this factor (multiply time_to_open with this value)*/
|
||||
#define LV_IMG_CACHE_LIFE_GAIN 1
|
||||
|
||||
/*Don't let life to be greater than this limit because it would require a lot of time to
|
||||
* "die" from very high values */
|
||||
#define LV_IMG_CACHE_LIFE_LIMIT 1000
|
||||
|
||||
#if LV_IMG_CACHE_DEF_SIZE < 1
|
||||
#error "LV_IMG_CACHE_DEF_SIZE must be >= 1. See lv_conf.h"
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint16_t entry_cnt;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Open an image using the image decoder interface and cache it.
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style)
|
||||
{
|
||||
if(entry_cnt == 0) {
|
||||
LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);
|
||||
|
||||
/*Decrement all lifes. Make the entries older*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
if(cache[i].life > INT32_MIN + LV_IMG_CACHE_AGING) {
|
||||
cache[i].life -= LV_IMG_CACHE_AGING;
|
||||
}
|
||||
}
|
||||
|
||||
/*Is the image cached?*/
|
||||
lv_img_cache_entry_t * cached_src = NULL;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
if(cache[i].dec_dsc.src == src) {
|
||||
/* If opened increment its life.
|
||||
* Image difficult to open should live longer to keep avoid frequent their recaching.
|
||||
* Therefore increase `life` with `time_to_open`*/
|
||||
cached_src = &cache[i];
|
||||
cached_src->life += cached_src->dec_dsc.time_to_open * LV_IMG_CACHE_LIFE_GAIN;
|
||||
if(cached_src->life > LV_IMG_CACHE_LIFE_LIMIT) cached_src->life = LV_IMG_CACHE_LIFE_LIMIT;
|
||||
LV_LOG_TRACE("image draw: image found in the cache");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*The image is not cached then cache it now*/
|
||||
if(cached_src == NULL) {
|
||||
/*Find an entry to reuse. Select the entry with the least life*/
|
||||
cached_src = &cache[0];
|
||||
for(i = 1; i < entry_cnt; i++) {
|
||||
if(cache[i].life < cached_src->life) {
|
||||
cached_src = &cache[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*Close the decoder to reuse if it was opened (has a valid source)*/
|
||||
if(cached_src->dec_dsc.src) {
|
||||
lv_img_decoder_close(&cached_src->dec_dsc);
|
||||
LV_LOG_INFO("image draw: cache miss, close and reuse an entry");
|
||||
} else {
|
||||
LV_LOG_INFO("image draw: cache miss, cached to an empty entry");
|
||||
}
|
||||
|
||||
/*Open the image and measure the time to open*/
|
||||
uint32_t t_start;
|
||||
t_start = lv_tick_get();
|
||||
cached_src->dec_dsc.time_to_open = 0;
|
||||
lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, style);
|
||||
if(open_res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw cannot open the image resource");
|
||||
lv_img_decoder_close(&cached_src->dec_dsc);
|
||||
memset(&cached_src->dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(cached_src, 0, sizeof(lv_img_cache_entry_t));
|
||||
cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cached_src->life = 0;
|
||||
|
||||
/*If `time_to_open` was not set in the open function set it here*/
|
||||
if(cached_src->dec_dsc.time_to_open == 0) {
|
||||
cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);
|
||||
}
|
||||
|
||||
if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;
|
||||
}
|
||||
|
||||
return cached_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of images to be cached.
|
||||
* More cached images mean more opened image at same time which might mean more memory usage.
|
||||
* E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.
|
||||
* @param new_entry_cnt number of image to cache
|
||||
*/
|
||||
void lv_img_cache_set_size(uint16_t new_entry_cnt)
|
||||
{
|
||||
if(LV_GC_ROOT(_lv_img_cache_array) != NULL) {
|
||||
/*Clean the cache before free it*/
|
||||
lv_img_cache_invalidate_src(NULL);
|
||||
lv_mem_free(LV_GC_ROOT(_lv_img_cache_array));
|
||||
}
|
||||
|
||||
/*Reallocate the cache*/
|
||||
LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_img_cache_array));
|
||||
if(LV_GC_ROOT(_lv_img_cache_array) == NULL) {
|
||||
entry_cnt = 0;
|
||||
return;
|
||||
}
|
||||
entry_cnt = new_entry_cnt;
|
||||
|
||||
/*Clean the cache*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
memset(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(&LV_GC_ROOT(_lv_img_cache_array)[i], 0, sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate an image source in the cache.
|
||||
* Useful if the image source is updated therefore it needs to be cached again.
|
||||
* @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.
|
||||
*/
|
||||
void lv_img_cache_invalidate_src(const void * src)
|
||||
{
|
||||
|
||||
lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);
|
||||
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
if(cache[i].dec_dsc.src == src || src == NULL) {
|
||||
if(cache[i].dec_dsc.src != NULL) {
|
||||
lv_img_decoder_close(&cache[i].dec_dsc);
|
||||
}
|
||||
|
||||
memset(&cache[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(&cache[i], 0, sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
78
extended-setup/components/lvgl/src/lv_draw/lv_img_cache.h
Normal file
78
extended-setup/components/lvgl/src/lv_draw/lv_img_cache.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file lv_img_cache.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMG_CACHE_H
|
||||
#define LV_IMG_CACHE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* When loading images from the network it can take a long time to download and decode the image.
|
||||
*
|
||||
* To avoid repeating this heavy load images can be cached.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lv_img_decoder_dsc_t dec_dsc; /**< Image information */
|
||||
|
||||
/** Count the cache entries's life. Add `time_tio_open` to `life` when the entry is used.
|
||||
* Decrement all lifes by one every in every ::lv_img_cache_open.
|
||||
* If life == 0 the entry can be reused */
|
||||
int32_t life;
|
||||
} lv_img_cache_entry_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Open an image using the image decoder interface and cache it.
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Set the number of images to be cached.
|
||||
* More cached images mean more opened image at same time which might mean more memory usage.
|
||||
* E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.
|
||||
* @param new_entry_cnt number of image to cache
|
||||
*/
|
||||
void lv_img_cache_set_size(uint16_t new_slot_num);
|
||||
|
||||
/**
|
||||
* Invalidate an image source in the cache.
|
||||
* Useful if the image source is updated therefore it needs to be cached again.
|
||||
* @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.
|
||||
*/
|
||||
void lv_img_cache_invalidate_src(const void * src);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMG_CACHE_H*/
|
||||
723
extended-setup/components/lvgl/src/lv_draw/lv_img_decoder.c
Normal file
723
extended-setup/components/lvgl/src/lv_draw/lv_img_decoder.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/**
|
||||
* @file lv_img_decoder.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define CF_BUILT_IN_FIRST LV_IMG_CF_TRUE_COLOR
|
||||
#define CF_BUILT_IN_LAST LV_IMG_CF_ALPHA_8BIT
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct
|
||||
{
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_file_t * f;
|
||||
#endif
|
||||
lv_color_t * palette;
|
||||
} lv_img_decoder_built_in_data_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
* */
|
||||
void lv_img_decoder_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));
|
||||
|
||||
lv_img_decoder_t * decoder;
|
||||
|
||||
/*Create a decoder for the built in color format*/
|
||||
decoder = lv_img_decoder_create();
|
||||
if(decoder == NULL) {
|
||||
LV_LOG_WARN("lv_img_decoder_init: out of memory");
|
||||
lv_mem_assert(decoder);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_img_decoder_set_info_cb(decoder, lv_img_decoder_built_in_info);
|
||||
lv_img_decoder_set_open_cb(decoder, lv_img_decoder_built_in_open);
|
||||
lv_img_decoder_set_read_line_cb(decoder, lv_img_decoder_built_in_read_line);
|
||||
lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. E.g. file name or variable.
|
||||
* @param header the image info will be stored here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
|
||||
*/
|
||||
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
|
||||
{
|
||||
header->always_zero = 0;
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
|
||||
{
|
||||
res = LV_RES_INV;
|
||||
if(d->info_cb) {
|
||||
res = d->info_cb(d, src, header);
|
||||
if(res == LV_RES_OK) break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an image.
|
||||
* Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
|
||||
* @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)
|
||||
{
|
||||
dsc->style = style;
|
||||
dsc->src = src;
|
||||
dsc->src_type = lv_img_src_get_type(src);
|
||||
dsc->user_data = NULL;
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
|
||||
{
|
||||
/*Info an Open callbacks are required*/
|
||||
if(d->info_cb == NULL || d->open_cb == NULL) continue;
|
||||
|
||||
res = d->info_cb(d, src, &dsc->header);
|
||||
if(res != LV_RES_OK) continue;
|
||||
|
||||
dsc->error_msg = NULL;
|
||||
dsc->img_data = NULL;
|
||||
dsc->decoder = d;
|
||||
|
||||
res = d->open_cb(d, dsc);
|
||||
|
||||
/*Opened successfully. It is a good decoder to for this image source*/
|
||||
if(res == LV_RES_OK) break;
|
||||
}
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
memset(dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a line from an opened image
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
* @param x start X coordinate (from left)
|
||||
* @param y start Y coordinate (from top)
|
||||
* @param len number of pixels to read
|
||||
* @param buf store the data here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: an error occurred
|
||||
*/
|
||||
lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
lv_res_t res = LV_RES_INV;
|
||||
if(dsc->decoder->read_line_cb) res = dsc->decoder->read_line_cb(dsc->decoder, dsc, x, y, len, buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a decoding session
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
*/
|
||||
void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->decoder) {
|
||||
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_img_decoder_t * lv_img_decoder_create(void)
|
||||
{
|
||||
lv_img_decoder_t * decoder;
|
||||
decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
|
||||
lv_mem_assert(decoder);
|
||||
if(decoder == NULL) return NULL;
|
||||
|
||||
memset(decoder, 0, sizeof(lv_img_decoder_t));
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image decoder
|
||||
* @param decoder pointer to an image decoder
|
||||
*/
|
||||
void lv_img_decoder_delete(lv_img_decoder_t * decoder)
|
||||
{
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);
|
||||
lv_mem_free(decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to get information about the image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
|
||||
*/
|
||||
void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb)
|
||||
{
|
||||
decoder->info_cb = info_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to open an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param open_cb a function to open an image
|
||||
*/
|
||||
void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb)
|
||||
{
|
||||
decoder->open_cb = open_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to a decoded line of an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param read_line_cb a function to read a line of an image
|
||||
*/
|
||||
void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb)
|
||||
{
|
||||
decoder->read_line_cb = read_line_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to close a decoding session. E.g. close files and free other resources.
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param close_cb a function to close a decoding session
|
||||
*/
|
||||
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb)
|
||||
{
|
||||
decoder->close_cb = close_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info about a built-in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
|
||||
* @param header store the image data here
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src);
|
||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
lv_img_cf_t cf = ((lv_img_dsc_t *)src)->header.cf;
|
||||
if(cf < CF_BUILT_IN_FIRST || cf > CF_BUILT_IN_LAST) return LV_RES_INV;
|
||||
|
||||
header->w = ((lv_img_dsc_t *)src)->header.w;
|
||||
header->h = ((lv_img_dsc_t *)src)->header.h;
|
||||
header->cf = ((lv_img_dsc_t *)src)->header.cf;
|
||||
}
|
||||
#if LV_USE_FILESYSTEM
|
||||
else if(src_type == LV_IMG_SRC_FILE) {
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res;
|
||||
uint32_t rn;
|
||||
res = lv_fs_open(&file, src, LV_FS_MODE_RD);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn);
|
||||
lv_fs_close(&file);
|
||||
}
|
||||
|
||||
lv_img_cf_t cf = ((lv_img_dsc_t *)src)->header.cf;
|
||||
if(cf < CF_BUILT_IN_FIRST || cf > CF_BUILT_IN_LAST) return LV_RES_INV;
|
||||
|
||||
}
|
||||
#endif
|
||||
else if(src_type == LV_IMG_SRC_SYMBOL) {
|
||||
/*The size depend on the font but it is unknown here. It should be handled outside of the
|
||||
* function*/
|
||||
header->w = 1;
|
||||
header->h = 1;
|
||||
/* Symbols always have transparent parts. Important because of cover check in the design
|
||||
* function. The actual value doesn't matter because lv_draw_label will draw it*/
|
||||
header->cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
} else {
|
||||
LV_LOG_WARN("Image get info found unknown src type");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a built in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
/*Open the file if it's a file*/
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
/*Support only "*.bin" files*/
|
||||
if(strcmp(lv_fs_get_ext(dsc->src), "bin")) return LV_RES_INV;
|
||||
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_WARN("Built-in image decoder can't open the file");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*If the file was open successfully save the file descriptor*/
|
||||
if(dsc->user_data == NULL) {
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
user_data->f = lv_mem_alloc(sizeof(f));
|
||||
if(user_data->f == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(user_data->f);
|
||||
}
|
||||
|
||||
memcpy(user_data->f, &f, sizeof(f));
|
||||
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
lv_img_cf_t cf = dsc->header.cf;
|
||||
/*Process true color formats*/
|
||||
if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
/* In case of uncompressed formats the image stored in the ROM/RAM.
|
||||
* So simply give its pointer*/
|
||||
dsc->img_data = ((lv_img_dsc_t *)dsc->src)->data;
|
||||
return LV_RES_OK;
|
||||
} else {
|
||||
/*If it's a file it need to be read line by line later*/
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
}
|
||||
/*Process indexed images. Build a palette*/
|
||||
else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || cf == LV_IMG_CF_INDEXED_4BIT ||
|
||||
cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
|
||||
#if LV_IMG_CF_INDEXED
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(cf);
|
||||
uint32_t palette_size = 1 << px_size;
|
||||
|
||||
/*Allocate the palette*/
|
||||
if(dsc->user_data == NULL) {
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
user_data->palette = lv_mem_alloc(palette_size * sizeof(lv_color_t));
|
||||
if(user_data->palette == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_mem_assert(user_data->f);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
/*Read the palette from file*/
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, 4); /*Skip the header*/
|
||||
lv_fs_read(user_data->f, user_data->palette, palette_size * sizeof(lv_color_t), NULL);
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
} else {
|
||||
/*The palette begins in the beginning of the image data. Just point to it.*/
|
||||
lv_color32_t * palette_p = (lv_color32_t *)((lv_img_dsc_t *)dsc->src)->data;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < palette_size; i++) {
|
||||
user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);
|
||||
}
|
||||
}
|
||||
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
/*Alpha indexed images. */
|
||||
else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || cf == LV_IMG_CF_ALPHA_4BIT ||
|
||||
cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
#if LV_IMG_CF_ALPHA
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK; /*Nothing to process*/
|
||||
#else
|
||||
LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
/*Unknown format. Can't decode it.*/
|
||||
else {
|
||||
/*Free the potentially allocated memories*/
|
||||
lv_img_decoder_built_in_close(decoder, dsc);
|
||||
|
||||
LV_LOG_WARN("Image decoder open: unknown color format")
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
|
||||
lv_coord_t y, lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
|
||||
dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
/* For TRUE_COLOR images read line required only for files.
|
||||
* For variables the image data was returned in `open`*/
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf);
|
||||
}
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
|
||||
res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || dsc->header.cf == LV_IMG_CF_INDEXED_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf);
|
||||
} else {
|
||||
LV_LOG_WARN("Built-in image decoder read not supports the color format");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
if(user_data) {
|
||||
#if LV_USE_FILESYSTEM
|
||||
if(user_data->f) {
|
||||
lv_fs_close(user_data->f);
|
||||
lv_mem_free(user_data->f);
|
||||
}
|
||||
#endif
|
||||
if(user_data->palette) lv_mem_free(user_data->palette);
|
||||
|
||||
lv_mem_free(user_data);
|
||||
|
||||
dsc->user_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
lv_fs_res_t res;
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
|
||||
uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3;
|
||||
pos += 4; /*Skip the header*/
|
||||
res = lv_fs_seek(user_data->f, pos);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_WARN("Built-in image decoder seek failed");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
uint32_t btr = len * (px_size >> 3);
|
||||
uint32_t br = 0;
|
||||
lv_fs_read(user_data->f, buf, btr, &br);
|
||||
if(res != LV_FS_RES_OK || btr != br) {
|
||||
LV_LOG_WARN("Built-in image decoder read failed");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
|
||||
#if LV_IMG_CF_ALPHA
|
||||
const lv_opa_t alpha1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const lv_opa_t alpha2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const lv_opa_t alpha4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
|
||||
/*Simply fill the buffer with the color. Later only the alpha value will be modified.*/
|
||||
lv_color_t bg_color = dsc->style->image.color;
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < len; i++) {
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF;
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
*((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full;
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
const lv_opa_t * opa_table = NULL;
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/
|
||||
|
||||
lv_coord_t w = 0;
|
||||
uint32_t ofs = 0;
|
||||
int8_t pos = 0;
|
||||
switch(dsc->header.cf) {
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
|
||||
if(dsc->header.w & 0x7) w++;
|
||||
ofs += w * y + (x >> 3); /*First pixel*/
|
||||
pos = 7 - (x & 0x7);
|
||||
opa_table = alpha1_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x3) w++;
|
||||
ofs += w * y + (x >> 2); /*First pixel*/
|
||||
pos = 6 - ((x & 0x3) * 2);
|
||||
opa_table = alpha2_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x1) w++;
|
||||
ofs += w * y + (x >> 1); /*First pixel*/
|
||||
pos = 4 - ((x & 0x1) * 4);
|
||||
opa_table = alpha4_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
|
||||
ofs += w * y + x; /*First pixel*/
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
uint8_t fs_buf[LV_HOR_RES_MAX];
|
||||
#endif
|
||||
|
||||
const uint8_t * data_tmp = NULL;
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = dsc->src;
|
||||
|
||||
data_tmp = img_dsc->data + ofs;
|
||||
} else {
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
|
||||
lv_fs_read(user_data->f, fs_buf, w, NULL);
|
||||
data_tmp = fs_buf;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0");
|
||||
data_tmp = NULL; /*To avoid warnings*/
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t byte_act = 0;
|
||||
uint8_t val_act;
|
||||
for(i = 0; i < len; i++) {
|
||||
val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;
|
||||
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] =
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act];
|
||||
|
||||
pos -= px_size;
|
||||
if(pos < 0) {
|
||||
pos = 8 - px_size;
|
||||
data_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
|
||||
#if LV_IMG_CF_INDEXED
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/
|
||||
|
||||
lv_coord_t w = 0;
|
||||
int8_t pos = 0;
|
||||
uint32_t ofs = 0;
|
||||
switch(dsc->header.cf) {
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
|
||||
if(dsc->header.w & 0x7) w++;
|
||||
ofs += w * y + (x >> 3); /*First pixel*/
|
||||
ofs += 8; /*Skip the palette*/
|
||||
pos = 7 - (x & 0x7);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x3) w++;
|
||||
ofs += w * y + (x >> 2); /*First pixel*/
|
||||
ofs += 16; /*Skip the palette*/
|
||||
pos = 6 - ((x & 0x3) * 2);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x1) w++;
|
||||
ofs += w * y + (x >> 1); /*First pixel*/
|
||||
ofs += 64; /*Skip the palette*/
|
||||
pos = 4 - ((x & 0x1) * 4);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
|
||||
ofs += w * y + x; /*First pixel*/
|
||||
ofs += 1024; /*Skip the palette*/
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
uint8_t fs_buf[LV_HOR_RES_MAX];
|
||||
#endif
|
||||
const uint8_t * data_tmp = NULL;
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = dsc->src;
|
||||
data_tmp = img_dsc->data + ofs;
|
||||
} else {
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
|
||||
lv_fs_read(user_data->f, fs_buf, w, NULL);
|
||||
data_tmp = fs_buf;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0");
|
||||
data_tmp = NULL; /*To avoid warnings*/
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t byte_act = 0;
|
||||
uint8_t val_act;
|
||||
lv_coord_t i;
|
||||
lv_color_t * cbuf = (lv_color_t *)buf;
|
||||
for(i = 0; i < len; i++) {
|
||||
val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;
|
||||
cbuf[i] = user_data->palette[val_act];
|
||||
|
||||
pos -= px_size;
|
||||
if(pos < 0) {
|
||||
pos = 8 - px_size;
|
||||
data_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
357
extended-setup/components/lvgl/src/lv_draw/lv_img_decoder.h
Normal file
357
extended-setup/components/lvgl/src/lv_draw/lv_img_decoder.h
Normal file
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
* @file lv_img_decoder.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMG_DEOCER_H
|
||||
#define LV_IMG_DEOCER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../lv_misc/lv_fs.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_core/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*If image pixels contains alpha we need to know how much byte is a pixel*/
|
||||
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 2
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 3
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 4
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Source of image. */
|
||||
enum {
|
||||
LV_IMG_SRC_VARIABLE, /** Binary/C variable */
|
||||
LV_IMG_SRC_FILE, /** File in filesystem */
|
||||
LV_IMG_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h) */
|
||||
LV_IMG_SRC_UNKNOWN, /** Unknown source */
|
||||
};
|
||||
|
||||
typedef uint8_t lv_img_src_t;
|
||||
/**
|
||||
* LittlevGL image header
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
||||
/* The first 8 bit is very important to distinguish the different source types.
|
||||
* For more info see `lv_img_get_src_type()` in lv_img.c */
|
||||
uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/
|
||||
uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
|
||||
non-printable character*/
|
||||
|
||||
uint32_t reserved : 2; /*Reserved to be used later*/
|
||||
|
||||
uint32_t w : 11; /*Width of the image map*/
|
||||
uint32_t h : 11; /*Height of the image map*/
|
||||
} lv_img_header_t;
|
||||
|
||||
/*Image color format*/
|
||||
enum {
|
||||
LV_IMG_CF_UNKNOWN = 0,
|
||||
|
||||
LV_IMG_CF_RAW, /**< Contains the file as it is. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW_ALPHA, /**< Contains the file as it is. The image has alpha. Needs custom decoder
|
||||
function*/
|
||||
LV_IMG_CF_RAW_CHROMA_KEYED, /**< Contains the file as it is. The image is chroma keyed. Needs
|
||||
custom decoder function*/
|
||||
|
||||
LV_IMG_CF_TRUE_COLOR, /**< Color format and depth should match with LV_COLOR settings*/
|
||||
LV_IMG_CF_TRUE_COLOR_ALPHA, /**< Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
|
||||
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /**< Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels
|
||||
will be transparent*/
|
||||
|
||||
LV_IMG_CF_INDEXED_1BIT, /**< Can have 2 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_2BIT, /**< Can have 4 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_4BIT, /**< Can have 16 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_8BIT, /**< Can have 256 different colors in a palette (always chroma keyed)*/
|
||||
|
||||
LV_IMG_CF_ALPHA_1BIT, /**< Can have one color and it can be drawn or not*/
|
||||
LV_IMG_CF_ALPHA_2BIT, /**< Can have one color but 4 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_4BIT, /**< Can have one color but 16 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_8BIT, /**< Can have one color but 256 different alpha value*/
|
||||
|
||||
LV_IMG_CF_RESERVED_15, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_16, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_17, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_18, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_19, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_20, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_21, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_22, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_23, /**< Reserved for further use. */
|
||||
|
||||
LV_IMG_CF_USER_ENCODED_0, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_1, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_2, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_3, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_4, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_5, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_6, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_7, /**< User holder encoding format. */
|
||||
};
|
||||
typedef uint8_t lv_img_cf_t;
|
||||
|
||||
/** Image header it is compatible with
|
||||
* the result from image converter utility*/
|
||||
typedef struct
|
||||
{
|
||||
lv_img_header_t header;
|
||||
uint32_t data_size;
|
||||
const uint8_t * data;
|
||||
} lv_img_dsc_t;
|
||||
|
||||
/* Decoder function definitions */
|
||||
|
||||
struct _lv_img_decoder;
|
||||
struct _lv_img_decoder_dsc;
|
||||
|
||||
/**
|
||||
* Get info from an image and store in the `header`
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use
|
||||
* `lv_img_src_get_type` to determine the type)
|
||||
* @param header store the info here
|
||||
* @return LV_RES_OK: info written correctly; LV_RES_INV: failed
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_info_f_t)(struct _lv_img_decoder * decoder, const void * src,
|
||||
lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image for decoding. Prepare it as it is required to read it later
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_open_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc,
|
||||
lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
typedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
|
||||
|
||||
typedef struct _lv_img_decoder
|
||||
{
|
||||
lv_img_decoder_info_f_t info_cb;
|
||||
lv_img_decoder_open_f_t open_cb;
|
||||
lv_img_decoder_read_line_f_t read_line_cb;
|
||||
lv_img_decoder_close_f_t close_cb;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_img_decoder_user_data_t user_data;
|
||||
#endif
|
||||
} lv_img_decoder_t;
|
||||
|
||||
/**Describe an image decoding session. Stores data about the decoding*/
|
||||
typedef struct _lv_img_decoder_dsc
|
||||
{
|
||||
/**The decoder which was able to open the image source*/
|
||||
lv_img_decoder_t * decoder;
|
||||
|
||||
/**The image source. A file path like "S:my_img.png" or pointer to an `lv_img_dsc_t` variable*/
|
||||
const void * src;
|
||||
|
||||
/**Style to draw the image.*/
|
||||
const lv_style_t * style;
|
||||
|
||||
/**Type of the source: file or variable. Can be set in `open` function if required*/
|
||||
lv_img_src_t src_type;
|
||||
|
||||
/**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
|
||||
lv_img_header_t header;
|
||||
|
||||
/** Pointer to a buffer where the image's data (pixels) are stored in a decoded, plain format.
|
||||
* MUST be set in `open` function*/
|
||||
const uint8_t * img_data;
|
||||
|
||||
/** How much time did it take to open the image. [ms]
|
||||
* If not set `lv_img_cache` will measure and set the time to open*/
|
||||
uint32_t time_to_open;
|
||||
|
||||
/**A text to display instead of the image when the image can't be opened.
|
||||
* Can be set in `open` function or set NULL. */
|
||||
const char * error_msg;
|
||||
|
||||
/**Store any custom data here is required*/
|
||||
void * user_data;
|
||||
} lv_img_decoder_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
*/
|
||||
void lv_img_decoder_init(void);
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param header the image info will be stored here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
|
||||
*/
|
||||
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image.
|
||||
* Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
|
||||
* @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Read a line from an opened image
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
* @param x start X coordinate (from left)
|
||||
* @param y start Y coordinate (from top)
|
||||
* @param len number of pixels to read
|
||||
* @param buf store the data here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: an error occurred
|
||||
*/
|
||||
lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len,
|
||||
uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close a decoding session
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
*/
|
||||
void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_img_decoder_t * lv_img_decoder_create(void);
|
||||
|
||||
/**
|
||||
* Delete an image decoder
|
||||
* @param decoder pointer to an image decoder
|
||||
*/
|
||||
void lv_img_decoder_delete(lv_img_decoder_t * decoder);
|
||||
|
||||
/**
|
||||
* Set a callback to get information about the image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
|
||||
*/
|
||||
void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to open an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param open_cb a function to open an image
|
||||
*/
|
||||
void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to a decoded line of an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param read_line_cb a function to read a line of an image
|
||||
*/
|
||||
void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to close a decoding session. E.g. close files and free other resources.
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param close_cb a function to close a decoding session
|
||||
*/
|
||||
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get info about a built-in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
|
||||
* @param header store the image data here
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open a built in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
|
||||
lv_coord_t y, lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
||||
84
extended-setup/components/lvgl/src/lv_font/lv_font.c
Normal file
84
extended-setup/components/lvgl/src/lv_font/lv_font.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file lv_font.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_font.h"
|
||||
#include "../lv_misc/lv_utils.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with the bitmap of a font.
|
||||
* @param font_p pointer to a font
|
||||
* @param letter an UNICODE character code
|
||||
* @return pointer to the bitmap of the letter
|
||||
*/
|
||||
const uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter)
|
||||
{
|
||||
return font_p->get_glyph_bitmap(font_p, letter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the descriptor of a glyph
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next)
|
||||
{
|
||||
return font_p->get_glyph_dsc(font_p, dsc_out, letter, letter_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of a glyph with kerning
|
||||
* @param font pointer to a font
|
||||
* @param letter an UNICODE letter
|
||||
* @param letter_next the next letter after `letter`. Used for kerning
|
||||
* @return the width of the glyph
|
||||
*/
|
||||
uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next)
|
||||
{
|
||||
lv_font_glyph_dsc_t g;
|
||||
bool ret;
|
||||
ret = lv_font_get_glyph_dsc(font, &g, letter, letter_next);
|
||||
if(ret) return g.adv_w;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
150
extended-setup/components/lvgl/src/lv_font/lv_font.h
Normal file
150
extended-setup/components/lvgl/src/lv_font/lv_font.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file lv_font.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FONT_H
|
||||
#define LV_FONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "lv_symbol_def.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Number of fractional digits in the advanced width (`adv_w`) field of `lv_font_glyph_dsc_t`*/
|
||||
#define LV_FONT_WIDTH_FRACT_DIGIT 4
|
||||
|
||||
#define LV_FONT_KERN_POSITIVE 0
|
||||
#define LV_FONT_KERN_NEGATIVE 1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*------------------
|
||||
* General types
|
||||
*-----------------*/
|
||||
|
||||
/** Describes the properties of a glyph. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */
|
||||
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||
int8_t ofs_y; /**< y offset of the bounding box*/
|
||||
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
||||
}lv_font_glyph_dsc_t;
|
||||
|
||||
/*Describe the properties of a font*/
|
||||
typedef struct _lv_font_struct
|
||||
{
|
||||
/** Get a glyph's descriptor from a font*/
|
||||
bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/** Get a glyph's bitmap from a font*/
|
||||
const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t);
|
||||
|
||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||
uint8_t line_height; /**< The real line height where any text fits*/
|
||||
uint8_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
void * dsc; /**< Store implementation specific data here*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
||||
#endif
|
||||
} lv_font_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with the bitmap of a font.
|
||||
* @param font_p pointer to a font
|
||||
* @param letter an UNICODE character code
|
||||
* @return pointer to the bitmap of the letter
|
||||
*/
|
||||
const uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter);
|
||||
|
||||
/**
|
||||
* Get the descriptor of a glyph
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/**
|
||||
* Get the width of a glyph with kerning
|
||||
* @param font pointer to a font
|
||||
* @param letter an UNICODE letter
|
||||
* @param letter_next the next letter after `letter`. Used for kerning
|
||||
* @return the width of the glyph
|
||||
*/
|
||||
uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/**
|
||||
* Get the line height of a font. All characters fit into this height
|
||||
* @param font_p pointer to a font
|
||||
* @return the height of a font
|
||||
*/
|
||||
static inline uint8_t lv_font_get_line_height(const lv_font_t * font_p)
|
||||
{
|
||||
return font_p->line_height;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_FONT_DECLARE(font_name) extern lv_font_t font_name;
|
||||
|
||||
#if LV_FONT_ROBOTO_12
|
||||
LV_FONT_DECLARE(lv_font_roboto_12)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_16
|
||||
LV_FONT_DECLARE(lv_font_roboto_16)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_22
|
||||
LV_FONT_DECLARE(lv_font_roboto_22)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_28
|
||||
LV_FONT_DECLARE(lv_font_roboto_28)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_UNSCII_8
|
||||
LV_FONT_DECLARE(lv_font_unscii_8)
|
||||
#endif
|
||||
|
||||
/*Declare the custom (user defined) fonts*/
|
||||
#ifdef LV_FONT_CUSTOM_DECLARE
|
||||
LV_FONT_CUSTOM_DECLARE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*USE_FONT*/
|
||||
12
extended-setup/components/lvgl/src/lv_font/lv_font.mk
Normal file
12
extended-setup/components/lvgl/src/lv_font/lv_font.mk
Normal file
@@ -0,0 +1,12 @@
|
||||
CSRCS += lv_font.c
|
||||
CSRCS += lv_font_fmt_txt.c
|
||||
CSRCS += lv_font_roboto_12.c
|
||||
CSRCS += lv_font_roboto_16.c
|
||||
CSRCS += lv_font_roboto_22.c
|
||||
CSRCS += lv_font_roboto_28.c
|
||||
CSRCS += lv_font_unscii_8.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_font
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_font
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/lvgl/src/lv_font"
|
||||
257
extended-setup/components/lvgl/src/lv_font/lv_font_fmt_txt.c
Normal file
257
extended-setup/components/lvgl/src/lv_font/lv_font_fmt_txt.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @file lv_font.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_font.h"
|
||||
#include "lv_font_fmt_txt.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter);
|
||||
static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t gid_right);
|
||||
static int32_t unicode_list_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_8_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_16_compare(const void * ref, const void * element);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
*/
|
||||
const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unicode_letter)
|
||||
{
|
||||
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
uint32_t gid = get_glyph_dsc_id(font, unicode_letter);
|
||||
if(!gid) return false;
|
||||
|
||||
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
|
||||
|
||||
if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
|
||||
|
||||
/*If not returned earlier then the letter is not found in this font*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
|
||||
{
|
||||
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
uint32_t gid = get_glyph_dsc_id(font, unicode_letter);
|
||||
if(!gid) return false;
|
||||
|
||||
int8_t kvalue = 0;
|
||||
if(fdsc->kern_dsc) {
|
||||
uint32_t gid_next = get_glyph_dsc_id(font, unicode_letter_next);
|
||||
if(gid_next) {
|
||||
kvalue = get_kern_value(font, gid, gid_next);
|
||||
}
|
||||
}
|
||||
|
||||
/*Put together a glyph dsc*/
|
||||
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
|
||||
|
||||
uint32_t adv_w = gdsc->adv_w + ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
|
||||
adv_w = (adv_w + (1 << 3)) >> 4;
|
||||
|
||||
dsc_out->adv_w = adv_w;
|
||||
dsc_out->box_h = gdsc->box_h;
|
||||
dsc_out->box_w = gdsc->box_w;
|
||||
dsc_out->ofs_x = gdsc->ofs_x;
|
||||
dsc_out->ofs_y = gdsc->ofs_y;
|
||||
dsc_out->bpp = fdsc->bpp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter)
|
||||
{
|
||||
if(letter == '\0') return 0;
|
||||
|
||||
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
|
||||
/*Check the chacge first*/
|
||||
if(letter == fdsc->last_letter) return fdsc->last_glyph_id;
|
||||
|
||||
uint16_t i;
|
||||
for(i = 0; i < fdsc->cmap_num; i++) {
|
||||
|
||||
/*Relative code point*/
|
||||
uint32_t rcp = letter - fdsc->cmaps[i].range_start;
|
||||
if(rcp > fdsc->cmaps[i].range_length) continue;
|
||||
uint32_t glyph_id = 0;
|
||||
if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY) {
|
||||
glyph_id = fdsc->cmaps[i].glyph_id_start + rcp;
|
||||
}
|
||||
else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL) {
|
||||
const uint8_t * gid_ofs_8 = fdsc->cmaps[i].glyph_id_ofs_list;
|
||||
glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_8[rcp];
|
||||
}
|
||||
else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY) {
|
||||
uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
|
||||
if(p) {
|
||||
uint32_t ofs = (lv_uintptr_t)p - (lv_uintptr_t) fdsc->cmaps[i].unicode_list;
|
||||
ofs = ofs >> 1; /*The list stores `uint16_t` so the get the index divide by 2*/
|
||||
glyph_id = fdsc->cmaps[i].glyph_id_start + ofs;
|
||||
}
|
||||
}
|
||||
else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL) {
|
||||
uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);
|
||||
|
||||
if(p) {
|
||||
uint32_t ofs = (lv_uintptr_t)p - (lv_uintptr_t) fdsc->cmaps[i].unicode_list;
|
||||
ofs = ofs >> 1; /*The list stores `uint16_t` so the get the index divide by 2*/
|
||||
const uint8_t * gid_ofs_16 = fdsc->cmaps[i].glyph_id_ofs_list;
|
||||
glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_16[ofs];
|
||||
}
|
||||
}
|
||||
|
||||
/*Update the cache*/
|
||||
fdsc->last_letter = letter;
|
||||
fdsc->last_glyph_id = glyph_id;
|
||||
return glyph_id;
|
||||
}
|
||||
|
||||
fdsc->last_letter = letter;
|
||||
fdsc->last_glyph_id = 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t gid_right)
|
||||
{
|
||||
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
|
||||
int8_t value = 0;
|
||||
|
||||
if(fdsc->kern_classes == 0) {
|
||||
/*Kern pairs*/
|
||||
const lv_font_fmt_txt_kern_pair_t * kdsc = fdsc->kern_dsc;
|
||||
if(kdsc->glyph_ids_size == 0) {
|
||||
/* Use binary search to find the kern value.
|
||||
* The pairs are ordered left_id first, then right_id secondly. */
|
||||
const uint8_t * g_ids = kdsc->glyph_ids;
|
||||
uint16_t g_id_both = (gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||
uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare);
|
||||
|
||||
/*If the `g_id_both` were found get its index from the pointer*/
|
||||
if(kid_p) {
|
||||
uint32_t ofs = (lv_uintptr_t)kid_p - (lv_uintptr_t)g_ids;
|
||||
ofs = ofs >> 1; /*ofs is for pair, divide by 2 to refer as a single value*/
|
||||
value = kdsc->values[ofs];
|
||||
}
|
||||
} else if(kdsc->glyph_ids_size == 1) {
|
||||
/* Use binary search to find the kern value.
|
||||
* The pairs are ordered left_id first, then right_id secondly. */
|
||||
const uint16_t * g_ids = kdsc->glyph_ids;
|
||||
uint32_t g_id_both = (uint32_t)((uint32_t)gid_right << 8) + gid_left; /*Create one number from the ids*/
|
||||
uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare);
|
||||
|
||||
/*If the `g_id_both` were found get its index from the pointer*/
|
||||
if(kid_p) {
|
||||
uint32_t ofs = (lv_uintptr_t)kid_p - (lv_uintptr_t)g_ids;
|
||||
ofs = ofs >> 4; /*ofs is 4 byte pairs, divide by 4 to refer as a single value*/
|
||||
value = kdsc->values[ofs];
|
||||
}
|
||||
|
||||
} else {
|
||||
/*Invalid value*/
|
||||
}
|
||||
} else {
|
||||
/*Kern classes*/
|
||||
const lv_font_fmt_txt_kern_classes_t * kdsc = fdsc->kern_dsc;
|
||||
uint8_t left_class = kdsc->left_class_mapping[gid_left];
|
||||
uint8_t right_class = kdsc->left_class_mapping[gid_right];
|
||||
|
||||
/* If class = 0, kerning not exist for that glyph
|
||||
* else got the value form `class_pair_values` 2D array*/
|
||||
if(left_class > 0 && right_class > 0) {
|
||||
value = kdsc->class_pair_values[(left_class-1)* kdsc->right_class_cnt + (right_class-1)];
|
||||
}
|
||||
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static int32_t kern_pair_8_compare(const void * ref, const void * element)
|
||||
{
|
||||
const uint8_t * ref8_p = ref;
|
||||
const uint8_t * element8_p = element;
|
||||
|
||||
/*If the MSB is different it will matter. If not return the diff. of the LSB*/
|
||||
if(ref8_p[0] != element8_p[0]) return (int32_t)ref8_p[0] - element8_p[0];
|
||||
else return (int32_t) ref8_p[1] - element8_p[1];
|
||||
|
||||
}
|
||||
|
||||
static int32_t kern_pair_16_compare(const void * ref, const void * element)
|
||||
{
|
||||
const uint16_t * ref16_p = ref;
|
||||
const uint16_t * element16_p = element;
|
||||
|
||||
/*If the MSB is different it will matter. If not return the diff. of the LSB*/
|
||||
if(ref16_p[0] != element16_p[0]) return (int32_t)ref16_p[0] - element16_p[0];
|
||||
else return (int32_t) ref16_p[1] - element16_p[1];
|
||||
}
|
||||
|
||||
/** Code Comparator.
|
||||
*
|
||||
* Compares the value of both input arguments.
|
||||
*
|
||||
* @param[in] pRef Pointer to the reference.
|
||||
* @param[in] pElement Pointer to the element to compare.
|
||||
*
|
||||
* @return Result of comparison.
|
||||
* @retval < 0 Reference is greater than element.
|
||||
* @retval = 0 Reference is equal to element.
|
||||
* @retval > 0 Reference is less than element.
|
||||
*
|
||||
*/
|
||||
static int32_t unicode_list_compare(const void * ref, const void * element)
|
||||
{
|
||||
return (*(uint16_t *)ref) - (*(uint16_t *)element);
|
||||
}
|
||||
233
extended-setup/components/lvgl/src/lv_font/lv_font_fmt_txt.h
Normal file
233
extended-setup/components/lvgl/src/lv_font/lv_font_fmt_txt.h
Normal file
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @file lv_font.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FONT_FMT_TXT_H
|
||||
#define LV_FONT_FMT_TXT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_font.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** This describes a glyph. */
|
||||
typedef struct
|
||||
{
|
||||
#if LV_FONT_FMT_TXT_LARGE == 0
|
||||
uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB. */
|
||||
uint32_t adv_w :12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored). */
|
||||
#else
|
||||
uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB. */
|
||||
uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored). */
|
||||
#endif
|
||||
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||
uint8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
||||
}lv_font_fmt_txt_glyph_dsc_t;
|
||||
|
||||
|
||||
/** Format of font character map. */
|
||||
typedef enum {
|
||||
LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,
|
||||
LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL,
|
||||
LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,
|
||||
LV_FONT_FMT_TXT_CMAP_SPARSE_FULL,
|
||||
}lv_font_fmt_txt_cmap_type_t;
|
||||
|
||||
|
||||
/* Map codepoints to a `glyph_dsc`s
|
||||
* Several formats are supported to optimize memory usage
|
||||
* See https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
*/
|
||||
typedef struct {
|
||||
/** First Unicode character for this range */
|
||||
uint32_t range_start;
|
||||
|
||||
/** Number of Unicode characters related to this range.
|
||||
* Last Unicode character = range_start + range_length - 1*/
|
||||
uint16_t range_length;
|
||||
|
||||
/** First glyph ID (array index of `glyph_dsc`) for this range */
|
||||
uint16_t glyph_id_start;
|
||||
|
||||
/*
|
||||
According the specification there are 4 formats:
|
||||
https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
||||
|
||||
For simplicity introduce "relative code point":
|
||||
rcp = codepoint - range_start
|
||||
|
||||
and a search function:
|
||||
search a "value" in an "array" and returns the index of "value".
|
||||
|
||||
Format 0 tiny
|
||||
unicode_list == NULL && glyph_id_ofs_list == NULL
|
||||
glyph_id = glyph_id_start + rcp
|
||||
|
||||
Format 0 full
|
||||
unicode_list == NULL && glyph_id_ofs_list != NULL
|
||||
glyph_id = glyph_id_start + glyph_id_ofs_list[rcp]
|
||||
|
||||
Sparse tiny
|
||||
unicode_list != NULL && glyph_id_ofs_list == NULL
|
||||
glyph_id = glyph_id_start + search(unicode_list, rcp)
|
||||
|
||||
Sparse full
|
||||
unicode_list != NULL && glyph_id_ofs_list != NULL
|
||||
glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)]
|
||||
*/
|
||||
|
||||
uint16_t * unicode_list;
|
||||
|
||||
/** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *`
|
||||
* if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *`
|
||||
*/
|
||||
const void * glyph_id_ofs_list;
|
||||
|
||||
/** Length of `unicode_list` and/or `glyph_id_ofs_list`*/
|
||||
uint16_t list_length;
|
||||
|
||||
/** Type of this character map*/
|
||||
lv_font_fmt_txt_cmap_type_t type :2;
|
||||
}lv_font_fmt_txt_cmap_t;
|
||||
|
||||
/** A simple mapping of kern values from pairs*/
|
||||
typedef struct {
|
||||
/*To get a kern value of two code points:
|
||||
1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t
|
||||
2 for(i = 0; i < pair_cnt * 2; i+2)
|
||||
if(gylph_ids[i] == glyph_id_left &&
|
||||
gylph_ids[i+1] == glyph_id_right)
|
||||
return values[i / 2];
|
||||
*/
|
||||
const void * glyph_ids;
|
||||
const int8_t * values;
|
||||
uint32_t pair_cnt :24;
|
||||
uint32_t glyph_ids_size :2; /*0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t`*/
|
||||
}lv_font_fmt_txt_kern_pair_t;
|
||||
|
||||
/** More complex but more optimal class based kern value storage*/
|
||||
typedef struct {
|
||||
/*To get a kern value of two code points:
|
||||
1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t
|
||||
2 Get the class of the left and right glyphs as `left_class` and `right_class`
|
||||
left_class = left_class_mapping[glyph_id_left];
|
||||
right_class = right_class_mapping[glyph_id_right];
|
||||
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
|
||||
*/
|
||||
|
||||
const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/
|
||||
const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
||||
const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
||||
uint8_t left_class_cnt;
|
||||
uint8_t right_class_cnt;
|
||||
}lv_font_fmt_txt_kern_classes_t;
|
||||
|
||||
|
||||
/** Bitmap formats*/
|
||||
typedef enum {
|
||||
LV_FONT_FMT_TXT_PLAIN = 0,
|
||||
LV_FONT_FMT_TXT_COMPRESSED = 1,
|
||||
}lv_font_fmt_txt_bitmap_format_t;
|
||||
|
||||
|
||||
/*Describe store additional data for fonts */
|
||||
typedef struct {
|
||||
/*The bitmaps os all glyphs*/
|
||||
const uint8_t * glyph_bitmap;
|
||||
|
||||
/*Describe the glyphs*/
|
||||
const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc;
|
||||
|
||||
/* Map the glyphs to Unicode characters.
|
||||
* Array of `lv_font_cmap_fmt_txt_t` variables*/
|
||||
const lv_font_fmt_txt_cmap_t * cmaps;
|
||||
|
||||
/* Store kerning values.
|
||||
* Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *`
|
||||
* depending on `kern_classes`
|
||||
*/
|
||||
const void * kern_dsc;
|
||||
|
||||
/*Scale kern values in 12.4 format*/
|
||||
uint16_t kern_scale;
|
||||
|
||||
/*Number of cmap tables*/
|
||||
uint16_t cmap_num :10;
|
||||
|
||||
/*Bit per pixel: 1, 2, 4 or 8*/
|
||||
uint16_t bpp :3;
|
||||
|
||||
/*Type of `kern_dsc`*/
|
||||
uint16_t kern_classes :1;
|
||||
|
||||
/*
|
||||
* storage format of the bitmap
|
||||
* from `lv_font_fmt_txt_bitmap_format_t`
|
||||
*/
|
||||
uint16_t bitmap_format :2;
|
||||
|
||||
/*Cache the last letter and is glyph id*/
|
||||
uint32_t last_letter;
|
||||
uint32_t last_glyph_id;
|
||||
|
||||
}lv_font_fmt_txt_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.
|
||||
* @param font pointer to font
|
||||
* @param unicode_letter an unicode letter which bitmap should be get
|
||||
* @return pointer to the bitmap or NULL if not found
|
||||
*/
|
||||
const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter);
|
||||
|
||||
/**
|
||||
* Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* ADD BUILT IN FONTS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_FONT_FMT_TXT_H*/
|
||||
1501
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_12.c
Normal file
1501
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_12.c
Normal file
File diff suppressed because it is too large
Load Diff
1963
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_16.c
Normal file
1963
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_16.c
Normal file
File diff suppressed because it is too large
Load Diff
2874
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_22.c
Normal file
2874
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_22.c
Normal file
File diff suppressed because it is too large
Load Diff
4024
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_28.c
Normal file
4024
extended-setup/components/lvgl/src/lv_font/lv_font_roboto_28.c
Normal file
File diff suppressed because it is too large
Load Diff
463
extended-setup/components/lvgl/src/lv_font/lv_font_unscii_8.c
Normal file
463
extended-setup/components/lvgl/src/lv_font/lv_font_unscii_8.c
Normal file
@@ -0,0 +1,463 @@
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Size: 8 px
|
||||
* Bpp: 1
|
||||
* Opts:
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LV_FONT_UNSCII_8
|
||||
#define LV_FONT_UNSCII_8 1
|
||||
#endif
|
||||
|
||||
#if LV_FONT_UNSCII_8
|
||||
|
||||
/*-----------------
|
||||
* BITMAPS
|
||||
*----------------*/
|
||||
|
||||
/*Store the image of the glyphs*/
|
||||
static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
|
||||
/* U+20 " " */
|
||||
|
||||
/* U+21 "!" */
|
||||
0xf2,
|
||||
|
||||
/* U+22 "\"" */
|
||||
0x99, 0x90,
|
||||
|
||||
/* U+23 "#" */
|
||||
0x49, 0x2f, 0xd2, 0xfd, 0x24, 0x80,
|
||||
|
||||
/* U+24 "$" */
|
||||
0x23, 0xe8, 0xe2, 0xf8, 0x80,
|
||||
|
||||
/* U+25 "%" */
|
||||
0xc7, 0x21, 0x8, 0x4e, 0x30,
|
||||
|
||||
/* U+26 "&" */
|
||||
0x62, 0x49, 0x18, 0x96, 0x27, 0x40,
|
||||
|
||||
/* U+27 "'" */
|
||||
0x2a, 0x0,
|
||||
|
||||
/* U+28 "(" */
|
||||
0x2a, 0x48, 0x88,
|
||||
|
||||
/* U+29 ")" */
|
||||
0x88, 0x92, 0xa0,
|
||||
|
||||
/* U+2A "*" */
|
||||
0x25, 0x5c, 0x47, 0x54, 0x80,
|
||||
|
||||
/* U+2B "+" */
|
||||
0x21, 0x3e, 0x42, 0x0,
|
||||
|
||||
/* U+2C "," */
|
||||
0x58,
|
||||
|
||||
/* U+2D "-" */
|
||||
0xf8,
|
||||
|
||||
/* U+2E "." */
|
||||
0x80,
|
||||
|
||||
/* U+2F "/" */
|
||||
0x2, 0x8, 0x20, 0x82, 0x8, 0x20, 0x0,
|
||||
|
||||
/* U+30 "0" */
|
||||
0x74, 0x67, 0x5c, 0xc5, 0xc0,
|
||||
|
||||
/* U+31 "1" */
|
||||
0x23, 0x28, 0x42, 0x13, 0xe0,
|
||||
|
||||
/* U+32 "2" */
|
||||
0x74, 0x42, 0x26, 0x43, 0xe0,
|
||||
|
||||
/* U+33 "3" */
|
||||
0x74, 0x42, 0x60, 0xc5, 0xc0,
|
||||
|
||||
/* U+34 "4" */
|
||||
0x11, 0x95, 0x2f, 0x88, 0x40,
|
||||
|
||||
/* U+35 "5" */
|
||||
0xfc, 0x3c, 0x10, 0xc5, 0xc0,
|
||||
|
||||
/* U+36 "6" */
|
||||
0x3a, 0x21, 0xe8, 0xc5, 0xc0,
|
||||
|
||||
/* U+37 "7" */
|
||||
0xf8, 0x44, 0x44, 0x21, 0x0,
|
||||
|
||||
/* U+38 "8" */
|
||||
0x74, 0x62, 0xe8, 0xc5, 0xc0,
|
||||
|
||||
/* U+39 "9" */
|
||||
0x74, 0x62, 0xf0, 0x8b, 0x80,
|
||||
|
||||
/* U+3A ":" */
|
||||
0x90,
|
||||
|
||||
/* U+3B ";" */
|
||||
0x41, 0x60,
|
||||
|
||||
/* U+3C "<" */
|
||||
0x12, 0x48, 0x42, 0x10,
|
||||
|
||||
/* U+3D "=" */
|
||||
0xf8, 0x3e,
|
||||
|
||||
/* U+3E ">" */
|
||||
0x84, 0x21, 0x24, 0x80,
|
||||
|
||||
/* U+3F "?" */
|
||||
0x7a, 0x10, 0x84, 0x10, 0x1, 0x0,
|
||||
|
||||
/* U+40 "@" */
|
||||
0x7a, 0x19, 0x6b, 0x9a, 0x7, 0x80,
|
||||
|
||||
/* U+41 "A" */
|
||||
0x31, 0x28, 0x7f, 0x86, 0x18, 0x40,
|
||||
|
||||
/* U+42 "B" */
|
||||
0xfa, 0x18, 0x7e, 0x86, 0x1f, 0x80,
|
||||
|
||||
/* U+43 "C" */
|
||||
0x7a, 0x18, 0x20, 0x82, 0x17, 0x80,
|
||||
|
||||
/* U+44 "D" */
|
||||
0xf2, 0x28, 0x61, 0x86, 0x2f, 0x0,
|
||||
|
||||
/* U+45 "E" */
|
||||
0xfe, 0x8, 0x3c, 0x82, 0xf, 0xc0,
|
||||
|
||||
/* U+46 "F" */
|
||||
0xfe, 0x8, 0x3c, 0x82, 0x8, 0x0,
|
||||
|
||||
/* U+47 "G" */
|
||||
0x7a, 0x18, 0x27, 0x86, 0x17, 0x80,
|
||||
|
||||
/* U+48 "H" */
|
||||
0x86, 0x18, 0x7f, 0x86, 0x18, 0x40,
|
||||
|
||||
/* U+49 "I" */
|
||||
0xe9, 0x24, 0xb8,
|
||||
|
||||
/* U+4A "J" */
|
||||
0x8, 0x42, 0x10, 0xc5, 0xc0,
|
||||
|
||||
/* U+4B "K" */
|
||||
0x86, 0x29, 0x38, 0x92, 0x28, 0x40,
|
||||
|
||||
/* U+4C "L" */
|
||||
0x82, 0x8, 0x20, 0x82, 0xf, 0xc0,
|
||||
|
||||
/* U+4D "M" */
|
||||
0x87, 0x3b, 0x61, 0x86, 0x18, 0x40,
|
||||
|
||||
/* U+4E "N" */
|
||||
0x87, 0x1a, 0x65, 0x8e, 0x18, 0x40,
|
||||
|
||||
/* U+4F "O" */
|
||||
0x7a, 0x18, 0x61, 0x86, 0x17, 0x80,
|
||||
|
||||
/* U+50 "P" */
|
||||
0xfa, 0x18, 0x7e, 0x82, 0x8, 0x0,
|
||||
|
||||
/* U+51 "Q" */
|
||||
0x7a, 0x18, 0x61, 0x96, 0x27, 0x40,
|
||||
|
||||
/* U+52 "R" */
|
||||
0xfa, 0x18, 0x7e, 0x92, 0x28, 0x40,
|
||||
|
||||
/* U+53 "S" */
|
||||
0x7a, 0x18, 0x1e, 0x6, 0x17, 0x80,
|
||||
|
||||
/* U+54 "T" */
|
||||
0xf9, 0x8, 0x42, 0x10, 0x80,
|
||||
|
||||
/* U+55 "U" */
|
||||
0x86, 0x18, 0x61, 0x86, 0x17, 0x80,
|
||||
|
||||
/* U+56 "V" */
|
||||
0x86, 0x18, 0x61, 0x85, 0x23, 0x0,
|
||||
|
||||
/* U+57 "W" */
|
||||
0x86, 0x18, 0x61, 0xb7, 0x38, 0x40,
|
||||
|
||||
/* U+58 "X" */
|
||||
0x86, 0x14, 0x8c, 0x4a, 0x18, 0x40,
|
||||
|
||||
/* U+59 "Y" */
|
||||
0x8c, 0x62, 0xe2, 0x10, 0x80,
|
||||
|
||||
/* U+5A "Z" */
|
||||
0xf8, 0x44, 0x44, 0x43, 0xe0,
|
||||
|
||||
/* U+5B "[" */
|
||||
0xf2, 0x49, 0x38,
|
||||
|
||||
/* U+5C "\\" */
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
|
||||
/* U+5D "]" */
|
||||
0xe4, 0x92, 0x78,
|
||||
|
||||
/* U+5E "^" */
|
||||
0x22, 0xa2,
|
||||
|
||||
/* U+5F "_" */
|
||||
0xf8,
|
||||
|
||||
/* U+60 "`" */
|
||||
0x88, 0x80,
|
||||
|
||||
/* U+61 "a" */
|
||||
0x70, 0x5f, 0x17, 0x80,
|
||||
|
||||
/* U+62 "b" */
|
||||
0x84, 0x3d, 0x18, 0xc7, 0xc0,
|
||||
|
||||
/* U+63 "c" */
|
||||
0x74, 0x61, 0x17, 0x0,
|
||||
|
||||
/* U+64 "d" */
|
||||
0x8, 0x5f, 0x18, 0xc5, 0xe0,
|
||||
|
||||
/* U+65 "e" */
|
||||
0x74, 0x7f, 0x7, 0x0,
|
||||
|
||||
/* U+66 "f" */
|
||||
0x18, 0x92, 0x3e, 0x20, 0x82, 0x0,
|
||||
|
||||
/* U+67 "g" */
|
||||
0x7c, 0x62, 0xf0, 0xb8,
|
||||
|
||||
/* U+68 "h" */
|
||||
0x84, 0x3d, 0x18, 0xc6, 0x20,
|
||||
|
||||
/* U+69 "i" */
|
||||
0x43, 0x24, 0xb8,
|
||||
|
||||
/* U+6A "j" */
|
||||
0x10, 0x31, 0x11, 0x96,
|
||||
|
||||
/* U+6B "k" */
|
||||
0x84, 0x23, 0x2e, 0x4a, 0x20,
|
||||
|
||||
/* U+6C "l" */
|
||||
0xc9, 0x24, 0xb8,
|
||||
|
||||
/* U+6D "m" */
|
||||
0xd5, 0x6b, 0x5a, 0x80,
|
||||
|
||||
/* U+6E "n" */
|
||||
0xf4, 0x63, 0x18, 0x80,
|
||||
|
||||
/* U+6F "o" */
|
||||
0x74, 0x63, 0x17, 0x0,
|
||||
|
||||
/* U+70 "p" */
|
||||
0xf4, 0x63, 0xe8, 0x40,
|
||||
|
||||
/* U+71 "q" */
|
||||
0x7c, 0x62, 0xf0, 0x84,
|
||||
|
||||
/* U+72 "r" */
|
||||
0xbe, 0x21, 0x8, 0x0,
|
||||
|
||||
/* U+73 "s" */
|
||||
0x7c, 0x1c, 0x1f, 0x0,
|
||||
|
||||
/* U+74 "t" */
|
||||
0x42, 0x3c, 0x84, 0x24, 0xc0,
|
||||
|
||||
/* U+75 "u" */
|
||||
0x8c, 0x63, 0x17, 0x0,
|
||||
|
||||
/* U+76 "v" */
|
||||
0x8c, 0x62, 0xa2, 0x0,
|
||||
|
||||
/* U+77 "w" */
|
||||
0x8d, 0x6b, 0x55, 0x0,
|
||||
|
||||
/* U+78 "x" */
|
||||
0x8a, 0x88, 0xa8, 0x80,
|
||||
|
||||
/* U+79 "y" */
|
||||
0x8c, 0x62, 0xf0, 0xb8,
|
||||
|
||||
/* U+7A "z" */
|
||||
0xf8, 0x88, 0x8f, 0x80,
|
||||
|
||||
/* U+7B "{" */
|
||||
0x34, 0x48, 0x44, 0x30,
|
||||
|
||||
/* U+7C "|" */
|
||||
0xff,
|
||||
|
||||
/* U+7D "}" */
|
||||
0xc2, 0x21, 0x22, 0xc0,
|
||||
|
||||
/* U+7E "~" */
|
||||
0x45, 0x44,
|
||||
|
||||
/* U+7F "" */
|
||||
0xc1, 0x42, 0xbd, 0x2c, 0x40, 0x81, 0x0
|
||||
};
|
||||
|
||||
|
||||
/*---------------------
|
||||
* GLYPH DESCRIPTION
|
||||
*--------------------*/
|
||||
|
||||
static lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
|
||||
{.bitmap_index = 0, .adv_w = 128, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 0, .adv_w = 128, .box_h = 7, .box_w = 1, .ofs_x = 3, .ofs_y = -1},
|
||||
{.bitmap_index = 1, .adv_w = 128, .box_h = 3, .box_w = 4, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 3, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 9, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 14, .adv_w = 128, .box_h = 6, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 19, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 25, .adv_w = 128, .box_h = 3, .box_w = 3, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 27, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 30, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 33, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 38, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 42, .adv_w = 128, .box_h = 3, .box_w = 2, .ofs_x = 3, .ofs_y = -2},
|
||||
{.bitmap_index = 43, .adv_w = 128, .box_h = 1, .box_w = 5, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 44, .adv_w = 128, .box_h = 1, .box_w = 1, .ofs_x = 3, .ofs_y = -1},
|
||||
{.bitmap_index = 45, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1},
|
||||
{.bitmap_index = 52, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 57, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 62, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 67, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 72, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 77, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 82, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 87, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 92, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 97, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 102, .adv_w = 128, .box_h = 4, .box_w = 1, .ofs_x = 3, .ofs_y = 0},
|
||||
{.bitmap_index = 103, .adv_w = 128, .box_h = 6, .box_w = 2, .ofs_x = 2, .ofs_y = -2},
|
||||
{.bitmap_index = 105, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 109, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 111, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 115, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 121, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 127, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 133, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 139, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 145, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 151, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 157, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 163, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 169, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 175, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 178, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 183, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 189, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 195, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 201, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 207, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 213, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 219, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 225, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 231, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 237, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 242, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 248, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 254, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 260, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 266, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 271, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 276, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 279, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1},
|
||||
{.bitmap_index = 286, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 289, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 291, .adv_w = 128, .box_h = 1, .box_w = 5, .ofs_x = 1, .ofs_y = -2},
|
||||
{.bitmap_index = 292, .adv_w = 128, .box_h = 3, .box_w = 3, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 294, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 298, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 303, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 307, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 312, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 316, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 322, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},
|
||||
{.bitmap_index = 326, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 331, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 334, .adv_w = 128, .box_h = 8, .box_w = 4, .ofs_x = 2, .ofs_y = -2},
|
||||
{.bitmap_index = 338, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 343, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 346, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 350, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 354, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 358, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},
|
||||
{.bitmap_index = 362, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},
|
||||
{.bitmap_index = 366, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 370, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 374, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 379, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 383, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 387, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 391, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 395, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},
|
||||
{.bitmap_index = 399, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 403, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 407, .adv_w = 128, .box_h = 8, .box_w = 1, .ofs_x = 3, .ofs_y = -2},
|
||||
{.bitmap_index = 408, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 2, .ofs_y = -1},
|
||||
{.bitmap_index = 412, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 414, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1}
|
||||
};
|
||||
|
||||
/*---------------------
|
||||
* CHARACTER MAPPING
|
||||
*--------------------*/
|
||||
|
||||
|
||||
|
||||
/*Collect the unicode lists and glyph_id offsets*/
|
||||
static const lv_font_fmt_txt_cmap_t cmaps[] =
|
||||
{
|
||||
{
|
||||
.range_start = 32, .range_length = 96, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,
|
||||
.glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*--------------------
|
||||
* ALL CUSTOM DATA
|
||||
*--------------------*/
|
||||
|
||||
/*Store all the custom data of the font*/
|
||||
static lv_font_fmt_txt_dsc_t font_dsc = {
|
||||
.glyph_bitmap = gylph_bitmap,
|
||||
.glyph_dsc = glyph_dsc,
|
||||
.cmaps = cmaps,
|
||||
.cmap_num = 1,
|
||||
.bpp = 1,
|
||||
|
||||
.kern_scale = 0,
|
||||
.kern_dsc = NULL,
|
||||
.kern_classes = 0,
|
||||
};
|
||||
|
||||
|
||||
/*-----------------
|
||||
* PUBLIC FONT
|
||||
*----------------*/
|
||||
|
||||
/*Initialize a public general font descriptor*/
|
||||
lv_font_t lv_font_unscii_8 = {
|
||||
.dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
|
||||
.get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/
|
||||
.get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/
|
||||
.line_height = 8, /*The maximum line height required by the font*/
|
||||
.base_line = 2, /*Baseline measured from the bottom of the line*/
|
||||
};
|
||||
|
||||
#endif /*#if LV_FONT_UNSCII_8*/
|
||||
|
||||
137
extended-setup/components/lvgl/src/lv_font/lv_symbol_def.h
Normal file
137
extended-setup/components/lvgl/src/lv_font/lv_symbol_def.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef LV_SYMBOL_DEF_H
|
||||
#define LV_SYMBOL_DEF_H
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define LV_SYMBOL_AUDIO "\xef\x80\x81"
|
||||
#define LV_SYMBOL_VIDEO "\xef\x80\x88"
|
||||
#define LV_SYMBOL_LIST "\xef\x80\x8b"
|
||||
#define LV_SYMBOL_OK "\xef\x80\x8c"
|
||||
#define LV_SYMBOL_CLOSE "\xef\x80\x8d"
|
||||
#define LV_SYMBOL_POWER "\xef\x80\x91"
|
||||
#define LV_SYMBOL_SETTINGS "\xef\x80\x93"
|
||||
#define LV_SYMBOL_TRASH "\xef\x80\x94"
|
||||
#define LV_SYMBOL_HOME "\xef\x80\x95"
|
||||
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99"
|
||||
#define LV_SYMBOL_DRIVE "\xef\x80\x9c"
|
||||
#define LV_SYMBOL_REFRESH "\xef\x80\xa1"
|
||||
#define LV_SYMBOL_MUTE "\xef\x80\xa6"
|
||||
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7"
|
||||
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8"
|
||||
#define LV_SYMBOL_IMAGE "\xef\x80\xbe"
|
||||
#define LV_SYMBOL_EDIT "\xef\x81\x80"
|
||||
#define LV_SYMBOL_PREV "\xef\x81\x88"
|
||||
#define LV_SYMBOL_PLAY "\xef\x81\x8b"
|
||||
#define LV_SYMBOL_PAUSE "\xef\x81\x8c"
|
||||
#define LV_SYMBOL_STOP "\xef\x81\x8d"
|
||||
#define LV_SYMBOL_NEXT "\xef\x81\x91"
|
||||
#define LV_SYMBOL_EJECT "\xef\x81\x92"
|
||||
#define LV_SYMBOL_LEFT "\xef\x81\x93"
|
||||
#define LV_SYMBOL_RIGHT "\xef\x81\x94"
|
||||
#define LV_SYMBOL_PLUS "\xef\x81\xa7"
|
||||
#define LV_SYMBOL_MINUS "\xef\x81\xa8"
|
||||
#define LV_SYMBOL_WARNING "\xef\x81\xb1"
|
||||
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4"
|
||||
#define LV_SYMBOL_UP "\xef\x81\xb7"
|
||||
#define LV_SYMBOL_DOWN "\xef\x81\xb8"
|
||||
#define LV_SYMBOL_LOOP "\xef\x81\xb9"
|
||||
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb"
|
||||
#define LV_SYMBOL_UPLOAD "\xef\x82\x93"
|
||||
#define LV_SYMBOL_CALL "\xef\x82\x95"
|
||||
#define LV_SYMBOL_CUT "\xef\x83\x84"
|
||||
#define LV_SYMBOL_COPY "\xef\x83\x85"
|
||||
#define LV_SYMBOL_SAVE "\xef\x83\x87"
|
||||
#define LV_SYMBOL_CHARGE "\xef\x83\xa7"
|
||||
#define LV_SYMBOL_BELL "\xef\x83\xb3"
|
||||
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c"
|
||||
#define LV_SYMBOL_GPS "\xef\x84\xa4"
|
||||
#define LV_SYMBOL_FILE "\xef\x85\x9b"
|
||||
#define LV_SYMBOL_WIFI "\xef\x87\xab"
|
||||
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80"
|
||||
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81"
|
||||
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82"
|
||||
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83"
|
||||
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84"
|
||||
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93"
|
||||
|
||||
/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/
|
||||
#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF"
|
||||
|
||||
/*
|
||||
* The following list is generated using
|
||||
* cat src/lv_misc/lv_symbol_def.h | sed -E -n 's/^#define\s+(LV_SYMBOL_\w+).*"$/ _LV_STR_\1,/p'
|
||||
*/
|
||||
enum {
|
||||
_LV_STR_SYMBOL_AUDIO,
|
||||
_LV_STR_SYMBOL_VIDEO,
|
||||
_LV_STR_SYMBOL_LIST,
|
||||
_LV_STR_SYMBOL_OK,
|
||||
_LV_STR_SYMBOL_CLOSE,
|
||||
_LV_STR_SYMBOL_POWER,
|
||||
_LV_STR_SYMBOL_SETTINGS,
|
||||
_LV_STR_SYMBOL_TRASH,
|
||||
_LV_STR_SYMBOL_HOME,
|
||||
_LV_STR_SYMBOL_DOWNLOAD,
|
||||
_LV_STR_SYMBOL_DRIVE,
|
||||
_LV_STR_SYMBOL_REFRESH,
|
||||
_LV_STR_SYMBOL_MUTE,
|
||||
_LV_STR_SYMBOL_VOLUME_MID,
|
||||
_LV_STR_SYMBOL_VOLUME_MAX,
|
||||
_LV_STR_SYMBOL_IMAGE,
|
||||
_LV_STR_SYMBOL_EDIT,
|
||||
_LV_STR_SYMBOL_PREV,
|
||||
_LV_STR_SYMBOL_PLAY,
|
||||
_LV_STR_SYMBOL_PAUSE,
|
||||
_LV_STR_SYMBOL_STOP,
|
||||
_LV_STR_SYMBOL_NEXT,
|
||||
_LV_STR_SYMBOL_EJECT,
|
||||
_LV_STR_SYMBOL_LEFT,
|
||||
_LV_STR_SYMBOL_RIGHT,
|
||||
_LV_STR_SYMBOL_PLUS,
|
||||
_LV_STR_SYMBOL_MINUS,
|
||||
_LV_STR_SYMBOL_WARNING,
|
||||
_LV_STR_SYMBOL_SHUFFLE,
|
||||
_LV_STR_SYMBOL_UP,
|
||||
_LV_STR_SYMBOL_DOWN,
|
||||
_LV_STR_SYMBOL_LOOP,
|
||||
_LV_STR_SYMBOL_DIRECTORY,
|
||||
_LV_STR_SYMBOL_UPLOAD,
|
||||
_LV_STR_SYMBOL_CALL,
|
||||
_LV_STR_SYMBOL_CUT,
|
||||
_LV_STR_SYMBOL_COPY,
|
||||
_LV_STR_SYMBOL_SAVE,
|
||||
_LV_STR_SYMBOL_CHARGE,
|
||||
_LV_STR_SYMBOL_BELL,
|
||||
_LV_STR_SYMBOL_KEYBOARD,
|
||||
_LV_STR_SYMBOL_GPS,
|
||||
_LV_STR_SYMBOL_FILE,
|
||||
_LV_STR_SYMBOL_WIFI,
|
||||
_LV_STR_SYMBOL_BATTERY_FULL,
|
||||
_LV_STR_SYMBOL_BATTERY_3,
|
||||
_LV_STR_SYMBOL_BATTERY_2,
|
||||
_LV_STR_SYMBOL_BATTERY_1,
|
||||
_LV_STR_SYMBOL_BATTERY_EMPTY,
|
||||
_LV_STR_SYMBOL_BLUETOOTH,
|
||||
_LV_STR_SYMBOL_DUMMY,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_SYMBOL_DEF_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
40
extended-setup/components/lvgl/src/lv_hal/lv_hal.h
Normal file
40
extended-setup/components/lvgl/src/lv_hal/lv_hal.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file lv_hal.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_HAL_H
|
||||
#define LV_HAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_hal_disp.h"
|
||||
#include "lv_hal_indev.h"
|
||||
#include "lv_hal_tick.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
8
extended-setup/components/lvgl/src/lv_hal/lv_hal.mk
Normal file
8
extended-setup/components/lvgl/src/lv_hal/lv_hal.mk
Normal file
@@ -0,0 +1,8 @@
|
||||
CSRCS += lv_hal_disp.c
|
||||
CSRCS += lv_hal_indev.c
|
||||
CSRCS += lv_hal_tick.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_hal
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_hal
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/lvgl/src/lv_hal"
|
||||
357
extended-setup/components/lvgl/src/lv_hal/lv_hal_disp.c
Normal file
357
extended-setup/components/lvgl/src/lv_hal/lv_hal_disp.c
Normal file
@@ -0,0 +1,357 @@
|
||||
|
||||
/**
|
||||
* @file hal_disp.c
|
||||
*
|
||||
* @description HAL layer for display driver
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_disp_t * disp_def;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a display driver with default values.
|
||||
* It is used to surly have known values in the fields ant not memory junk.
|
||||
* After it you can set the fields.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
{
|
||||
memset(driver, 0, sizeof(lv_disp_drv_t));
|
||||
|
||||
driver->flush_cb = NULL;
|
||||
driver->hor_res = LV_HOR_RES_MAX;
|
||||
driver->ver_res = LV_VER_RES_MAX;
|
||||
driver->buffer = NULL;
|
||||
driver->rotated = 0;
|
||||
driver->color_chroma_key = LV_COLOR_TRANSP;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
driver->antialiasing = true;
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
driver->screen_transp = 1;
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU
|
||||
driver->gpu_blend_cb = NULL;
|
||||
driver->gpu_fill_cb = NULL;
|
||||
#endif
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
driver->user_data = NULL;
|
||||
#endif
|
||||
|
||||
driver->set_px_cb = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
* @param buf1 A buffer to be used by LittlevGL to draw the image.
|
||||
* Always has to specified and can't be NULL.
|
||||
* Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
|
||||
* Or a memory address e.g. in external SRAM
|
||||
* @param buf2 Optionally specify a second buffer to make image rendering and image flushing
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt)
|
||||
{
|
||||
memset(disp_buf, 0, sizeof(lv_disp_buf_t));
|
||||
|
||||
disp_buf->buf1 = buf1;
|
||||
disp_buf->buf2 = buf2;
|
||||
disp_buf->buf_act = disp_buf->buf1;
|
||||
disp_buf->size = size_in_px_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an initialized display driver.
|
||||
* Automatically set the first display as active.
|
||||
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new display or NULL on error
|
||||
*/
|
||||
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
{
|
||||
lv_disp_t * disp = lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
if(!disp) {
|
||||
lv_mem_assert(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t));
|
||||
memset(&disp->inv_area_joined, 0, sizeof(disp->inv_area_joined));
|
||||
memset(&disp->inv_areas, 0, sizeof(disp->inv_areas));
|
||||
lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));
|
||||
|
||||
if(disp_def == NULL) disp_def = disp;
|
||||
|
||||
lv_disp_t * disp_def_tmp = disp_def;
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the
|
||||
new display*/
|
||||
|
||||
disp->inv_p = 0;
|
||||
|
||||
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
|
||||
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
lv_obj_set_style(disp->top_layer, &lv_style_transp);
|
||||
lv_obj_set_style(disp->sys_layer, &lv_style_transp);
|
||||
|
||||
lv_obj_invalidate(disp->act_scr);
|
||||
|
||||
disp_def = disp_def_tmp; /*Revert the default display*/
|
||||
|
||||
/*Create a refresh task*/
|
||||
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
|
||||
lv_mem_assert(disp->refr_task);
|
||||
if(disp->refr_task == NULL) return NULL;
|
||||
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the driver in run time.
|
||||
* @param disp pointer to a display. (return value of `lv_disp_drv_register`)
|
||||
* @param new_drv pointer to the new driver
|
||||
*/
|
||||
void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)
|
||||
{
|
||||
memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));
|
||||
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr)
|
||||
{
|
||||
lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a display
|
||||
* @param disp pointer to display
|
||||
*/
|
||||
void lv_disp_remove(lv_disp_t * disp)
|
||||
{
|
||||
bool was_default = false;
|
||||
if(disp == lv_disp_get_default()) was_default = true;
|
||||
|
||||
/*Detach the input devices */
|
||||
lv_indev_t * indev;
|
||||
indev = lv_indev_get_next(NULL);
|
||||
while(indev) {
|
||||
if(indev->driver.disp == disp) {
|
||||
indev->driver.disp = NULL;
|
||||
}
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
lv_mem_free(disp);
|
||||
|
||||
if(was_default) lv_disp_set_default(lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a default screen. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
void lv_disp_set_default(lv_disp_t * disp)
|
||||
{
|
||||
disp_def = disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default display
|
||||
* @return pointer to the default display
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_default(void)
|
||||
{
|
||||
return disp_def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the horizontal resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
|
||||
if(disp == NULL)
|
||||
return LV_HOR_RES_MAX;
|
||||
else
|
||||
return disp->driver.rotated == 0 ? disp->driver.hor_res : disp->driver.ver_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the vertical resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
|
||||
if(disp == NULL)
|
||||
return LV_VER_RES_MAX;
|
||||
else
|
||||
return disp->driver.rotated == 0 ? disp->driver.ver_res : disp->driver.hor_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if anti-aliasing is enabled for a display or not
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return true: anti-aliasing is enabled; false: disabled
|
||||
*/
|
||||
bool lv_disp_get_antialiasing(lv_disp_t * disp)
|
||||
{
|
||||
#if LV_ANTIALIAS == 0
|
||||
return false;
|
||||
#else
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
if(disp == NULL) return false;
|
||||
|
||||
return disp->driver.antialiasing ? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Call in the display driver's `flush_cb` function when the flushing is finished
|
||||
* @param disp_drv pointer to display driver in `flush_cb` where this function is called
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
|
||||
{
|
||||
disp_drv->buffer->flushing = 0;
|
||||
|
||||
/*If the screen is transparent initialize it when the flushing is ready*/
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp_drv->screen_transp) {
|
||||
memset(disp_drv->buffer->buf_act, 0x00, disp_drv->buffer->size * sizeof(lv_color32_t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal buffer of a display
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the internal buffers
|
||||
*/
|
||||
lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp)
|
||||
{
|
||||
return disp->driver.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)
|
||||
{
|
||||
return disp->inv_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
{
|
||||
|
||||
if(disp->inv_p < num)
|
||||
disp->inv_p = 0;
|
||||
else
|
||||
disp->inv_p -= num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
|
||||
* `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_true_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
uint32_t scr_size = disp->driver.hor_res * disp->driver.ver_res;
|
||||
|
||||
if(lv_disp_is_double_buf(disp) && disp->driver.buffer->size == scr_size) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
292
extended-setup/components/lvgl/src/lv_hal/lv_hal_disp.h
Normal file
292
extended-setup/components/lvgl/src/lv_hal/lv_hal_disp.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
* @file lv_hal_disp.h
|
||||
*
|
||||
* @description Display Driver HAL interface header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_HAL_DISP_H
|
||||
#define LV_HAL_DISP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_INV_BUF_SIZE
|
||||
#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_FLUSH_READY
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _disp_t;
|
||||
struct _disp_drv_t;
|
||||
|
||||
/**
|
||||
* Structure for holding display buffer information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void * buf1; /**< First display buffer. */
|
||||
void * buf2; /**< Second display buffer. */
|
||||
|
||||
/*Internal, used by the library*/
|
||||
void * buf_act;
|
||||
uint32_t size; /*In pixel count*/
|
||||
lv_area_t area;
|
||||
volatile uint32_t flushing : 1;
|
||||
} lv_disp_buf_t;
|
||||
|
||||
/**
|
||||
* Display Driver structure to be registered by HAL
|
||||
*/
|
||||
typedef struct _disp_drv_t
|
||||
{
|
||||
|
||||
lv_coord_t hor_res; /**< Horizontal resolution. */
|
||||
lv_coord_t ver_res; /**< Vertical resolution. */
|
||||
|
||||
/** Pointer to a buffer initialized with `lv_disp_buf_init()`.
|
||||
* LittlevGL will use this buffer(s) to draw the screens contents */
|
||||
lv_disp_buf_t * buffer;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
uint32_t antialiasing : 1; /**< 1: antialiasing is enabled on this display. */
|
||||
#endif
|
||||
uint32_t rotated : 1; /**< 1: turn the display by 90 degree. @warning Does not update coordinates for you!*/
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
/**Handle if the the screen doesn't have a solid (opa == LV_OPA_COVER) background.
|
||||
* Use only if required because it's slower.*/
|
||||
uint32_t screen_transp : 1;
|
||||
#endif
|
||||
|
||||
/** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
|
||||
* called when finished */
|
||||
void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
|
||||
* E.g. round `y` to, 8, 16 ..) on a monochrome display*/
|
||||
void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);
|
||||
|
||||
/** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
|
||||
* Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
|
||||
* @note Much slower then drawing with supported color formats. */
|
||||
void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
|
||||
* number of flushed pixels */
|
||||
void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);
|
||||
|
||||
#if LV_USE_GPU
|
||||
/** OPTIONAL: Blend two memories using opacity (GPU only)*/
|
||||
void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length,
|
||||
lv_opa_t opa);
|
||||
|
||||
/** OPTIONAL: Fill a memory with a color (GPU only)*/
|
||||
void (*gpu_fill_cb)(struct _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);
|
||||
#endif
|
||||
|
||||
/** On CHROMA_KEYED images this color will be transparent.
|
||||
* `LV_COLOR_TRANSP` by default. (lv_conf.h)*/
|
||||
lv_color_t color_chroma_key;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_disp_drv_user_data_t user_data; /**< Custom display driver user data */
|
||||
#endif
|
||||
|
||||
} lv_disp_drv_t;
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
/**
|
||||
* Display structure.
|
||||
* ::lv_disp_drv_t is the first member of the structure.
|
||||
*/
|
||||
typedef struct _disp_t
|
||||
{
|
||||
/**< Driver to the display*/
|
||||
lv_disp_drv_t driver;
|
||||
|
||||
/**< A task which periodically checks the dirty areas and refreshes them*/
|
||||
lv_task_t * refr_task;
|
||||
|
||||
/** Screens of the display*/
|
||||
lv_ll_t scr_ll;
|
||||
struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
|
||||
struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
|
||||
struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
|
||||
|
||||
/** Invalidated (marked to redraw) areas*/
|
||||
lv_area_t inv_areas[LV_INV_BUF_SIZE];
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
uint32_t inv_p : 10;
|
||||
|
||||
/*Miscellaneous data*/
|
||||
uint32_t last_activity_time; /**< Last time there was activity on this display */
|
||||
} lv_disp_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a display driver with default values.
|
||||
* It is used to have known values in the fields and not junk in memory.
|
||||
* After it you can safely set only the fields you need.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Initialize a display buffer
|
||||
* @param disp_buf pointer `lv_disp_buf_t` variable to initialize
|
||||
* @param buf1 A buffer to be used by LittlevGL to draw the image.
|
||||
* Always has to specified and can't be NULL.
|
||||
* Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
|
||||
* Or a memory address e.g. in external SRAM
|
||||
* @param buf2 Optionally specify a second buffer to make image rendering and image flushing
|
||||
* (sending to the display) parallel.
|
||||
* In the `disp_drv->flush` you should use DMA or similar hardware to send
|
||||
* the image to the display in the background.
|
||||
* It lets LittlevGL to render next frame into the other buffer while previous is being
|
||||
* sent. Set to `NULL` if unused.
|
||||
* @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt);
|
||||
|
||||
/**
|
||||
* Register an initialized display driver.
|
||||
* Automatically set the first display as active.
|
||||
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new display or NULL on error
|
||||
*/
|
||||
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Update the driver in run time.
|
||||
* @param disp pointer to a display. (return value of `lv_disp_drv_register`)
|
||||
* @param new_drv pointer to the new driver
|
||||
*/
|
||||
void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv);
|
||||
|
||||
/**
|
||||
* Remove a display
|
||||
* @param disp pointer to display
|
||||
*/
|
||||
void lv_disp_remove(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Set a default screen. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
void lv_disp_set_default(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the default display
|
||||
* @return pointer to the default display
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_default(void);
|
||||
|
||||
/**
|
||||
* Get the horizontal resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the vertical resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get if anti-aliasing is enabled for a display or not
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return true: anti-aliasing is enabled; false: disabled
|
||||
*/
|
||||
bool lv_disp_get_antialiasing(lv_disp_t * disp);
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Call in the display driver's `flush_cb` function when the flushing is finished
|
||||
* @param disp_drv pointer to display driver in `flush_cb` where this function is called
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv);
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the internal buffer of a display
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the internal buffers
|
||||
*/
|
||||
lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
|
||||
* `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_true_double_buf(lv_disp_t * disp);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
157
extended-setup/components/lvgl/src/lv_hal/lv_hal_indev.c
Normal file
157
extended-setup/components/lvgl/src/lv_hal/lv_hal_indev.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @file hal_indev.c
|
||||
*
|
||||
* @description Input device HAL interface
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "lv_hal_disp.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an input device driver with default values.
|
||||
* It is used to surly have known values in the fields ant not memory junk.
|
||||
* After it you can set the fields.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||||
{
|
||||
memset(driver, 0, sizeof(lv_indev_drv_t));
|
||||
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
driver->drag_throw = LV_INDEV_DEF_DRAG_THROW;
|
||||
driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
|
||||
driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an initialized input device driver.
|
||||
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new input device or NULL on error
|
||||
*/
|
||||
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
{
|
||||
|
||||
if(driver->disp == NULL) driver->disp = lv_disp_get_default();
|
||||
|
||||
if(driver->disp == NULL) {
|
||||
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attache the indev to "
|
||||
"a display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_indev_t * indev = lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
if(!indev) {
|
||||
lv_mem_assert(indev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(indev, 0, sizeof(lv_indev_t));
|
||||
memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));
|
||||
|
||||
indev->proc.reset_query = 1;
|
||||
indev->cursor = NULL;
|
||||
indev->group = NULL;
|
||||
indev->btn_points = NULL;
|
||||
|
||||
indev->driver.read_task = lv_task_create(lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_MID, indev);
|
||||
|
||||
return indev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the driver in run time.
|
||||
* @param indev pointer to a input device. (return value of `lv_indev_drv_register`)
|
||||
* @param new_drv pointer to the new driver
|
||||
*/
|
||||
void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
|
||||
{
|
||||
memcpy(&indev->driver, new_drv, sizeof(lv_indev_drv_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next input device.
|
||||
* @param indev pointer to the current input device. NULL to initialize.
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter
|
||||
* is NULL
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL)
|
||||
return lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
else
|
||||
return lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from an input device.
|
||||
* @param indev pointer to an input device
|
||||
* @param data input device will write its data here
|
||||
* @return false: no more data; true: there more data to read (buffered)
|
||||
*/
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
bool cont = false;
|
||||
|
||||
memset(data, 0, sizeof(lv_indev_data_t));
|
||||
|
||||
/* For touchpad sometimes users don't the last pressed coordinate on release.
|
||||
* So be sure a coordinates are initialized to the last point */
|
||||
if(indev->driver.type == LV_INDEV_TYPE_POINTER) {
|
||||
data->point.x = indev->proc.types.pointer.act_point.x;
|
||||
data->point.y = indev->proc.types.pointer.act_point.y;
|
||||
}
|
||||
/*Similarly set at least the last key in case of the the user doesn't set it on release*/
|
||||
else if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) {
|
||||
data->key = indev->proc.types.keypad.last_key;
|
||||
}
|
||||
|
||||
if(indev->driver.read_cb) {
|
||||
LV_LOG_TRACE("idnev read started");
|
||||
cont = indev->driver.read_cb(&indev->driver, data);
|
||||
LV_LOG_TRACE("idnev read finished");
|
||||
} else {
|
||||
LV_LOG_WARN("indev function registered");
|
||||
}
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
213
extended-setup/components/lvgl/src/lv_hal/lv_hal_indev.h
Normal file
213
extended-setup/components/lvgl/src/lv_hal/lv_hal_indev.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @file lv_hal_indev.h
|
||||
*
|
||||
* @description Input Device HAL interface layer header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_HAL_INDEV_H
|
||||
#define LV_HAL_INDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_obj_t;
|
||||
struct _disp_t;
|
||||
struct _lv_indev_t;
|
||||
struct _lv_indev_drv_t;
|
||||
|
||||
/** Possible input device types*/
|
||||
enum {
|
||||
LV_INDEV_TYPE_NONE, /**< Uninitialized state*/
|
||||
LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/
|
||||
LV_INDEV_TYPE_KEYPAD, /**< Keypad or keyboard*/
|
||||
LV_INDEV_TYPE_BUTTON, /**< External (hardware button) which is assigned to a specific point of the
|
||||
screen*/
|
||||
LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/
|
||||
};
|
||||
typedef uint8_t lv_indev_type_t;
|
||||
|
||||
/** States for input devices*/
|
||||
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
|
||||
typedef uint8_t lv_indev_state_t;
|
||||
|
||||
/** Data structure passed to an input driver to fill */
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
||||
uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
||||
uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
||||
int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
|
||||
lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
||||
} lv_indev_data_t;
|
||||
|
||||
/** Initialized by the user and registered by 'lv_indev_add()'*/
|
||||
typedef struct _lv_indev_drv_t
|
||||
{
|
||||
|
||||
/**< Input device type*/
|
||||
lv_indev_type_t type;
|
||||
|
||||
/**< Function pointer to read input device data.
|
||||
* Return 'true' if there is more data to be read (buffered).
|
||||
* Most drivers can safely return 'false' */
|
||||
bool (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/** Called when an action happened on the input device.
|
||||
* The second parameter is the event from `lv_event_t`*/
|
||||
void (*feedback_cb)(struct _lv_indev_drv_t *, uint8_t);
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_indev_drv_user_data_t user_data;
|
||||
#endif
|
||||
|
||||
/**< Pointer to the assigned display*/
|
||||
struct _disp_t * disp;
|
||||
|
||||
/**< Task to read the periodically read the input device*/
|
||||
lv_task_t * read_task;
|
||||
|
||||
/**< Number of pixels to slide before actually drag the object*/
|
||||
uint8_t drag_limit;
|
||||
|
||||
/**< Drag throw slow-down in [%]. Greater value means faster slow-down */
|
||||
uint8_t drag_throw;
|
||||
|
||||
/**< Long press time in milliseconds*/
|
||||
uint16_t long_press_time;
|
||||
|
||||
/**< Repeated trigger period in long press [ms] */
|
||||
uint16_t long_press_rep_time;
|
||||
} lv_indev_drv_t;
|
||||
|
||||
/** Run time data of input devices
|
||||
* Internally used by the library, you should not need to touch it.
|
||||
*/
|
||||
typedef struct _lv_indev_proc_t
|
||||
{
|
||||
lv_indev_state_t state; /**< Current state of the input device. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{ /*Pointer and button data*/
|
||||
lv_point_t act_point; /**< Current point of input device. */
|
||||
lv_point_t last_point; /**< Last point of input device. */
|
||||
lv_point_t vect; /**< Difference between `act_point` and `last_point`. */
|
||||
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t drag_throw_vect;
|
||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_obj; /*The last obejct which was pressed (used by dragthrow and
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
|
||||
/*Flags*/
|
||||
uint8_t drag_limit_out : 1;
|
||||
uint8_t drag_in_prog : 1;
|
||||
} pointer;
|
||||
struct
|
||||
{ /*Keypad data*/
|
||||
lv_indev_state_t last_state;
|
||||
uint32_t last_key;
|
||||
} keypad;
|
||||
} types;
|
||||
|
||||
uint32_t pr_timestamp; /**< Pressed time stamp*/
|
||||
uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/
|
||||
|
||||
/*Flags*/
|
||||
uint8_t long_pr_sent : 1;
|
||||
uint8_t reset_query : 1;
|
||||
uint8_t disabled : 1;
|
||||
uint8_t wait_until_release : 1;
|
||||
} lv_indev_proc_t;
|
||||
|
||||
struct _lv_obj_t;
|
||||
struct _lv_group_t;
|
||||
|
||||
/** The main input device descriptor with driver, runtime data ('proc') and some additional
|
||||
* information*/
|
||||
typedef struct _lv_indev_t
|
||||
{
|
||||
lv_indev_drv_t driver;
|
||||
lv_indev_proc_t proc;
|
||||
struct _lv_obj_t * cursor; /**< Cursor for LV_INPUT_TYPE_POINTER*/
|
||||
struct _lv_group_t * group; /**< Keypad destination group*/
|
||||
const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed
|
||||
here by the buttons*/
|
||||
} lv_indev_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an input device driver with default values.
|
||||
* It is used to surly have known values in the fields ant not memory junk.
|
||||
* After it you can set the fields.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_indev_drv_init(lv_indev_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Register an initialized input device driver.
|
||||
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new input device or NULL on error
|
||||
*/
|
||||
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Update the driver in run time.
|
||||
* @param indev pointer to a input device. (return value of `lv_indev_drv_register`)
|
||||
* @param new_drv pointer to the new driver
|
||||
*/
|
||||
void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv);
|
||||
|
||||
/**
|
||||
* Get the next input device.
|
||||
* @param indev pointer to the current input device. NULL to initialize.
|
||||
* @return the next input devise or NULL if no more. Give the first input device when the parameter
|
||||
* is NULL
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Read data from an input device.
|
||||
* @param indev pointer to an input device
|
||||
* @param data input device will write its data here
|
||||
* @return false: no more data; true: there more data to read (buffered)
|
||||
*/
|
||||
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
100
extended-setup/components/lvgl/src/lv_hal/lv_hal_tick.c
Normal file
100
extended-setup/components/lvgl/src/lv_hal/lv_hal_tick.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file systick.c
|
||||
* Provide access to the system tick with 1 millisecond resolution
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "lv_hal_tick.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#include LV_TICK_CUSTOM_INCLUDE
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t sys_time = 0;
|
||||
static volatile uint8_t tick_irq_flag;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* You have to call this function periodically
|
||||
* @param tick_period the call period of this function in milliseconds
|
||||
*/
|
||||
LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
|
||||
{
|
||||
tick_irq_flag = 0;
|
||||
sys_time += tick_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elapsed milliseconds since start up
|
||||
* @return the elapsed milliseconds
|
||||
*/
|
||||
uint32_t lv_tick_get(void)
|
||||
{
|
||||
#if LV_TICK_CUSTOM == 0
|
||||
uint32_t result;
|
||||
do {
|
||||
tick_irq_flag = 1;
|
||||
result = sys_time;
|
||||
} while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt.
|
||||
Continue until make a non interrupted cycle */
|
||||
|
||||
return result;
|
||||
#else
|
||||
return LV_TICK_CUSTOM_SYS_TIME_EXPR;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elapsed milliseconds since a previous time stamp
|
||||
* @param prev_tick a previous time stamp (return value of systick_get() )
|
||||
* @return the elapsed milliseconds since 'prev_tick'
|
||||
*/
|
||||
uint32_t lv_tick_elaps(uint32_t prev_tick)
|
||||
{
|
||||
uint32_t act_time = lv_tick_get();
|
||||
|
||||
/*If there is no overflow in sys_time simple subtract*/
|
||||
if(act_time >= prev_tick) {
|
||||
prev_tick = act_time - prev_tick;
|
||||
} else {
|
||||
prev_tick = UINT32_MAX - prev_tick + 1;
|
||||
prev_tick += act_time;
|
||||
}
|
||||
|
||||
return prev_tick;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
70
extended-setup/components/lvgl/src/lv_hal/lv_hal_tick.h
Normal file
70
extended-setup/components/lvgl/src/lv_hal/lv_hal_tick.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file lv_hal_tick.h
|
||||
* Provide access to the system tick with 1 millisecond resolution
|
||||
*/
|
||||
|
||||
#ifndef LV_HAL_TICK_H
|
||||
#define LV_HAL_TICK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_ATTRIBUTE_TICK_INC
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* You have to call this function periodically
|
||||
* @param tick_period the call period of this function in milliseconds
|
||||
*/
|
||||
LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period);
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Get the elapsed milliseconds since start up
|
||||
* @return the elapsed milliseconds
|
||||
*/
|
||||
uint32_t lv_tick_get(void);
|
||||
|
||||
/**
|
||||
* Get the elapsed milliseconds since a previous time stamp
|
||||
* @param prev_tick a previous time stamp (return value of systick_get() )
|
||||
* @return the elapsed milliseconds since 'prev_tick'
|
||||
*/
|
||||
uint32_t lv_tick_elaps(uint32_t prev_tick);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HAL_TICK_H*/
|
||||
473
extended-setup/components/lvgl/src/lv_misc/lv_anim.c
Normal file
473
extended-setup/components/lvgl/src/lv_misc/lv_anim.c
Normal file
@@ -0,0 +1,473 @@
|
||||
/**
|
||||
* @file anim.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_anim.h"
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "lv_task.h"
|
||||
#include "lv_math.h"
|
||||
#include "lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_ANIM_RESOLUTION 1024
|
||||
#define LV_ANIM_RES_SHIFT 10
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void anim_task(lv_task_t * param);
|
||||
static bool anim_ready_handler(lv_anim_t * a);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t last_task_run;
|
||||
static bool anim_list_changed;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the animation module
|
||||
*/
|
||||
void lv_anim_core_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));
|
||||
last_task_run = lv_tick_get();
|
||||
lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an animation variable.
|
||||
* E.g.:
|
||||
* lv_anim_t a;
|
||||
* lv_anim_init(&a);
|
||||
* lv_anim_set_...(&a);
|
||||
* lv_anim_craete(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_anim_init(lv_anim_t * a)
|
||||
{
|
||||
memset(a, 0, sizeof(lv_anim_t));
|
||||
a->time = 500;
|
||||
a->start = 0;
|
||||
a->end = 100;
|
||||
a->path_cb = lv_anim_path_linear;
|
||||
}
|
||||
/**
|
||||
* Create an animation
|
||||
* @param a an initialized 'anim_t' variable. Not required after call.
|
||||
*/
|
||||
void lv_anim_create(lv_anim_t * a)
|
||||
{
|
||||
LV_LOG_TRACE("animation create started")
|
||||
/* Do not let two animations for the same 'var' with the same 'fp'*/
|
||||
if(a->exec_cb != NULL) lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/
|
||||
|
||||
/*Add the new animation to the animation linked list*/
|
||||
lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
lv_mem_assert(new_anim);
|
||||
if(new_anim == NULL) return;
|
||||
|
||||
/*Initialize the animation descriptor*/
|
||||
a->playback_now = 0;
|
||||
memcpy(new_anim, a, sizeof(lv_anim_t));
|
||||
|
||||
/*Set the start value*/
|
||||
if(new_anim->exec_cb) new_anim->exec_cb(new_anim->var, new_anim->start);
|
||||
|
||||
/* Creating an animation changed the linked list.
|
||||
* It's important if it happens in a ready callback. (see `anim_task`)*/
|
||||
anim_list_changed = true;
|
||||
|
||||
LV_LOG_TRACE("animation created")
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an animation of a variable with a given animator function
|
||||
* @param var pointer to variable
|
||||
* @param exec_cb a function pointer which is animating 'var',
|
||||
* or NULL to delete all the animations of 'var'
|
||||
* @return true: at least 1 animation is deleted, false: no animation is deleted
|
||||
*/
|
||||
bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
{
|
||||
lv_anim_t * a;
|
||||
lv_anim_t * a_next;
|
||||
bool del = false;
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
while(a != NULL) {
|
||||
/*'a' might be deleted, so get the next object while 'a' is valid*/
|
||||
a_next = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
|
||||
if(a->var == var && (a->exec_cb == exec_cb || exec_cb == NULL)) {
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
anim_list_changed = true; /*Read by `anim_task`. It need to know if a delete occurred in
|
||||
the linked list*/
|
||||
del = true;
|
||||
}
|
||||
|
||||
a = a_next;
|
||||
}
|
||||
|
||||
return del;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of currently running animations
|
||||
* @return the number of running animations
|
||||
*/
|
||||
uint16_t lv_anim_count_running(void)
|
||||
{
|
||||
uint16_t cnt = 0;
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++;
|
||||
|
||||
return cnt++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the time of an animation with a given speed and the start and end values
|
||||
* @param speed speed of animation in unit/sec
|
||||
* @param start start value of the animation
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)
|
||||
{
|
||||
int32_t d = LV_MATH_ABS((int32_t)start - end);
|
||||
uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);
|
||||
|
||||
if(time > UINT16_MAX) time = UINT16_MAX;
|
||||
|
||||
if(time == 0) {
|
||||
time++;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying linear characteristic
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_linear(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint32_t step;
|
||||
if(a->time == a->act_time) {
|
||||
step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/
|
||||
} else {
|
||||
step = ((int32_t)a->act_time * LV_ANIM_RESOLUTION) / a->time;
|
||||
}
|
||||
|
||||
/* Get the new value which will be proportional to `step`
|
||||
* and the `start` and `end` values*/
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> LV_ANIM_RES_SHIFT;
|
||||
new_value += a->start;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation slowing down the start phase
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1, 1, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation slowing down the end phase
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_out(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying an "S" characteristic (cosine)
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 100, 924, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation with overshoot at the end
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_overshoot(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = lv_bezier3(t, 0, 600, 1300, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation with 3 bounces
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_bounce(const lv_anim_t * a)
|
||||
{
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t diff = (a->end - a->start);
|
||||
|
||||
/*3 bounces has 5 parts: 3 down and 2 up. One part is t / 5 long*/
|
||||
|
||||
if(t < 408) {
|
||||
/*Go down*/
|
||||
t = (t * 2500) >> 10; /*[0..1024] range*/
|
||||
} else if(t >= 408 && t < 614) {
|
||||
/*First bounce back*/
|
||||
t -= 408;
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
diff = diff / 6;
|
||||
} else if(t >= 614 && t < 819) {
|
||||
/*Fall back*/
|
||||
t -= 614;
|
||||
t = t * 5; /*to [0..1024] range*/
|
||||
diff = diff / 6;
|
||||
} else if(t >= 819 && t < 921) {
|
||||
/*Second bounce back*/
|
||||
t -= 819;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
t = 1024 - t;
|
||||
diff = diff / 16;
|
||||
} else if(t >= 921 && t <= 1024) {
|
||||
/*Fall back*/
|
||||
t -= 921;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
diff = diff / 16;
|
||||
}
|
||||
|
||||
if(t > 1024) t = 1024;
|
||||
|
||||
int32_t step = lv_bezier3(t, 1024, 1024, 800, 0);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * diff;
|
||||
new_value = new_value >> 10;
|
||||
new_value = a->end - new_value;
|
||||
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying step characteristic.
|
||||
* (Set end value on the end of the animation)
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_step(const lv_anim_t * a)
|
||||
{
|
||||
if(a->act_time >= a->time)
|
||||
return a->end;
|
||||
else
|
||||
return a->start;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Periodically handle the animations.
|
||||
* @param param unused
|
||||
*/
|
||||
static void anim_task(lv_task_t * param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
lv_anim_t * a;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a)
|
||||
{
|
||||
a->has_run = 0;
|
||||
}
|
||||
|
||||
uint32_t elaps = lv_tick_elaps(last_task_run);
|
||||
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
|
||||
while(a != NULL) {
|
||||
/*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete
|
||||
* happened in `anim_ready_handler` which could make this linked list reading corrupt
|
||||
* because the list is changed meanwhile
|
||||
*/
|
||||
anim_list_changed = false;
|
||||
|
||||
if(!a->has_run) {
|
||||
a->has_run = 1; /*The list readying might be reseted so need to know which anim has run already*/
|
||||
a->act_time += elaps;
|
||||
if(a->act_time >= 0) {
|
||||
if(a->act_time > a->time) a->act_time = a->time;
|
||||
|
||||
int32_t new_value;
|
||||
new_value = a->path_cb(a);
|
||||
|
||||
/*Apply the calculated value*/
|
||||
if(a->exec_cb) a->exec_cb(a->var, new_value);
|
||||
|
||||
/*If the time is elapsed the animation is ready*/
|
||||
if(a->act_time >= a->time) {
|
||||
anim_ready_handler(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the linked list changed due to anim. delete then it's not safe to continue
|
||||
* the reading of the list from here -> start from the head*/
|
||||
if(anim_list_changed)
|
||||
a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
else
|
||||
a = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
}
|
||||
|
||||
last_task_run = lv_tick_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an animation is ready to do the necessary thinks
|
||||
* e.g. repeat, play back, delete etc.
|
||||
* @param a pointer to an animation descriptor
|
||||
* @return true: animation delete occurred nnd the `LV_GC_ROOT(_lv_anim_ll)` has changed
|
||||
* */
|
||||
static bool anim_ready_handler(lv_anim_t * a)
|
||||
{
|
||||
|
||||
/*Delete the animation if
|
||||
* - no repeat and no play back (simple one shot animation)
|
||||
* - no repeat, play back is enabled and play back is ready */
|
||||
if((a->repeat == 0 && a->playback == 0) || (a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {
|
||||
|
||||
/*Create copy from the animation and delete the animation from the list.
|
||||
* This way the `ready_cb` will see the animations like it's animation is ready deleted*/
|
||||
lv_anim_t a_tmp;
|
||||
memcpy(&a_tmp, a, sizeof(lv_anim_t));
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);
|
||||
lv_mem_free(a);
|
||||
anim_list_changed = true;
|
||||
|
||||
/* Call the callback function at the end*/
|
||||
if(a_tmp.ready_cb != NULL) a_tmp.ready_cb(&a_tmp);
|
||||
}
|
||||
/*If the animation is not deleted then restart it*/
|
||||
else {
|
||||
a->act_time = -a->repeat_pause; /*Restart the animation*/
|
||||
/*Swap the start and end values in play back mode*/
|
||||
if(a->playback != 0) {
|
||||
/*If now turning back use the 'playback_pause*/
|
||||
if(a->playback_now == 0) a->act_time = -a->playback_pause;
|
||||
|
||||
/*Toggle the play back state*/
|
||||
a->playback_now = a->playback_now == 0 ? 1 : 0;
|
||||
/*Swap the start and end values*/
|
||||
int32_t tmp;
|
||||
tmp = a->start;
|
||||
a->start = a->end;
|
||||
a->end = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return anim_list_changed;
|
||||
}
|
||||
#endif
|
||||
331
extended-setup/components/lvgl/src/lv_misc/lv_anim.h
Normal file
331
extended-setup/components/lvgl/src/lv_misc/lv_anim.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
* @file anim.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANIM_H
|
||||
#define ANIM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Can be used to indicate if animations are enabled or disabled in a case*/
|
||||
enum {
|
||||
LV_ANIM_OFF,
|
||||
LV_ANIM_ON,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_anim_enable_t;
|
||||
|
||||
/** Type of the animated value*/
|
||||
typedef lv_coord_t lv_anim_value_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
struct _lv_anim_t;
|
||||
|
||||
/** Generic prototype of "animator" functions.
|
||||
* First parameter is the variable to animate.
|
||||
* Second parameter is the value to set.
|
||||
* Compatible with `lv_xxx_set_yyy(obj, value)` functions
|
||||
* The `x` in `_xcb_t` means its not a fully generic prototype because
|
||||
* it doesn't receive `lv_anim_t *` as its first argument*/
|
||||
typedef void (*lv_anim_exec_xcb_t)(void *, lv_anim_value_t);
|
||||
|
||||
/** Same as `lv_anim_exec_xcb_t` but receives `lv_anim_t *` as the first parameter.
|
||||
* It's more consistent but less convenient. Might be used by binding generator functions.*/
|
||||
typedef void (*lv_anim_custom_exec_cb_t)(struct _lv_anim_t *, lv_anim_value_t);
|
||||
|
||||
/** Get the current value during an animation*/
|
||||
typedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_t *);
|
||||
|
||||
/** Callback to call when the animation is ready*/
|
||||
typedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *);
|
||||
|
||||
/** Describes an animation*/
|
||||
typedef struct _lv_anim_t
|
||||
{
|
||||
void * var; /**<Variable to animate*/
|
||||
lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate*/
|
||||
lv_anim_path_cb_t path_cb; /**< Function to get the steps of animations*/
|
||||
lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/
|
||||
int32_t start; /**< Start value*/
|
||||
int32_t end; /**< End value*/
|
||||
uint16_t time; /**< Animation time in ms*/
|
||||
int16_t act_time; /**< Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /**< Wait before play back*/
|
||||
uint16_t repeat_pause; /**< Wait before repeat*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_anim_user_data_t user_data; /**< Custom user data*/
|
||||
#endif
|
||||
|
||||
uint8_t playback : 1; /**< When the animation is ready play it back*/
|
||||
uint8_t repeat : 1; /**< Repeat the animation infinitely*/
|
||||
/*Animation system use these - user shouldn't set*/
|
||||
uint8_t playback_now : 1; /**< Play back is in progress*/
|
||||
uint32_t has_run : 1; /**< Indicates the animation has run in this round*/
|
||||
} lv_anim_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the animation module
|
||||
*/
|
||||
void lv_anim_core_init(void);
|
||||
|
||||
/**
|
||||
* Initialize an animation variable.
|
||||
* E.g.:
|
||||
* lv_anim_t a;
|
||||
* lv_anim_init(&a);
|
||||
* lv_anim_set_...(&a);
|
||||
* lv_anim_create(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_anim_init(lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Set a variable to animate function to execute on `var`
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param var pointer to a variable to animate
|
||||
* @param exec_cb a function to execute.
|
||||
* LittelvGL's built-in functions can be used.
|
||||
* E.g. lv_obj_set_x
|
||||
*/
|
||||
static inline void lv_anim_set_exec_cb(lv_anim_t * a, void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
{
|
||||
a->var = var;
|
||||
a->exec_cb = exec_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration and delay of an animation
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param duration duration of the animation in milliseconds
|
||||
* @param delay delay before the animation in milliseconds
|
||||
*/
|
||||
static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)
|
||||
{
|
||||
a->time = duration;
|
||||
a->act_time = -delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the start and end values of an animation
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param start the start value
|
||||
* @param end the end value
|
||||
*/
|
||||
static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end)
|
||||
{
|
||||
a->start = start;
|
||||
a->end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to `lv_anim_set_var_and_cb` but `lv_anim_custom_exec_cb_t` receives
|
||||
* `lv_anim_t * ` as its first parameter instead of `void *`.
|
||||
* This function might be used when LittlevGL is binded to other languages because
|
||||
* it's more consistent to have `lv_anim_t *` as first parameter.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param exec_cb a function to execute.
|
||||
*/
|
||||
static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)
|
||||
{
|
||||
a->var = a;
|
||||
a->exec_cb = (lv_anim_exec_xcb_t)exec_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path (curve) of the animation.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param path_cb a function the get the current value of the animation.
|
||||
* The built in functions starts with `lv_anim_path_...`
|
||||
*/
|
||||
static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb)
|
||||
{
|
||||
a->path_cb = path_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function call when the animation is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param ready_cb a function call when the animation is ready
|
||||
*/
|
||||
static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)
|
||||
{
|
||||
a->ready_cb = ready_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to play back to when the forward direction is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the back direction
|
||||
*/
|
||||
static inline void lv_anim_set_playback(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
a->playback = 1;
|
||||
a->playback_pause = wait_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable playback. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_anim_clear_playback(lv_anim_t * a)
|
||||
{
|
||||
a->playback = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to start again when ready.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the animation again
|
||||
*/
|
||||
static inline void lv_anim_set_repeat(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
a->repeat = 1;
|
||||
a->repeat_pause = wait_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable repeat. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_anim_clear_repeat(lv_anim_t * a)
|
||||
{
|
||||
a->repeat = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation
|
||||
* @param a an initialized 'anim_t' variable. Not required after call.
|
||||
*/
|
||||
void lv_anim_create(lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Delete an animation of a variable with a given animator function
|
||||
* @param var pointer to variable
|
||||
* @param exec_cb a function pointer which is animating 'var',
|
||||
* or NULL to ignore it and delete all the animations of 'var
|
||||
* @return true: at least 1 animation is deleted, false: no animation is deleted
|
||||
*/
|
||||
bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb);
|
||||
|
||||
/**
|
||||
* Delete an aniamation by getting the animated variable from `a`.
|
||||
* Only animations with `exec_cb` will be deleted.
|
||||
* This function exist becasue it's logical that all anim functions receives an
|
||||
* `lv_anim_t` as their first parameter. It's not practical in C but might makes
|
||||
* the API more conequent and makes easier to genrate bindings.
|
||||
* @param a pointer to an animation.
|
||||
* @param exec_cb a function pointer which is animating 'var',
|
||||
* or NULL to ignore it and delete all the animations of 'var
|
||||
* @return true: at least 1 animation is deleted, false: no animation is deleted
|
||||
*/
|
||||
static inline bool lv_anim_custom_del(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)
|
||||
{
|
||||
return lv_anim_del(a->var, (lv_anim_exec_xcb_t)exec_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of currently running animations
|
||||
* @return the number of running animations
|
||||
*/
|
||||
uint16_t lv_anim_count_running(void);
|
||||
|
||||
/**
|
||||
* Calculate the time of an animation with a given speed and the start and end values
|
||||
* @param speed speed of animation in unit/sec
|
||||
* @param start start value of the animation
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying linear characteristic
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_linear(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation slowing down the start phase
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation slowing down the end phase
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_out(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying an "S" characteristic (cosine)
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation with overshoot at the end
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_overshoot(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation with 3 bounces
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_bounce(const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying step characteristic.
|
||||
* (Set end value on the end of the animation)
|
||||
* @param a pointer to an animation
|
||||
* @return the current value to set
|
||||
*/
|
||||
lv_anim_value_t lv_anim_path_step(const lv_anim_t * a);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ANIMATION == 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_ANIM_H*/
|
||||
197
extended-setup/components/lvgl/src/lv_misc/lv_area.c
Normal file
197
extended-setup/components/lvgl/src/lv_misc/lv_area.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @file lv_area.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "lv_area.h"
|
||||
#include "lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an area
|
||||
* @param area_p pointer to an area
|
||||
* @param x1 left coordinate of the area
|
||||
* @param y1 top coordinate of the area
|
||||
* @param x2 right coordinate of the area
|
||||
* @param y2 bottom coordinate of the area
|
||||
*/
|
||||
void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2)
|
||||
{
|
||||
area_p->x1 = x1;
|
||||
area_p->y1 = y1;
|
||||
area_p->x2 = x2;
|
||||
area_p->y2 = y2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width of an area
|
||||
* @param area_p pointer to an area
|
||||
* @param w the new width of the area (w == 1 makes x1 == x2)
|
||||
*/
|
||||
void lv_area_set_width(lv_area_t * area_p, lv_coord_t w)
|
||||
{
|
||||
area_p->x2 = area_p->x1 + w - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height of an area
|
||||
* @param area_p pointer to an area
|
||||
* @param h the new height of the area (h == 1 makes y1 == y2)
|
||||
*/
|
||||
void lv_area_set_height(lv_area_t * area_p, lv_coord_t h)
|
||||
{
|
||||
area_p->y2 = area_p->y1 + h - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the position of an area (width and height will be kept)
|
||||
* @param area_p pointer to an area
|
||||
* @param x the new x coordinate of the area
|
||||
* @param y the new y coordinate of the area
|
||||
*/
|
||||
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
area_p->x1 = x;
|
||||
area_p->y1 = y;
|
||||
lv_area_set_width(area_p, w);
|
||||
lv_area_set_height(area_p, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with area of an area (x * y)
|
||||
* @param area_p pointer to an area
|
||||
* @return size of area
|
||||
*/
|
||||
uint32_t lv_area_get_size(const lv_area_t * area_p)
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
size = (uint32_t)(area_p->x2 - area_p->x1 + 1) * (area_p->y2 - area_p->y1 + 1);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the common parts of two areas
|
||||
* @param res_p pointer to an area, the result will be stored here
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
* @return false: the two area has NO common parts, res_p is invalid
|
||||
*/
|
||||
bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
/* Get the smaller area from 'a1_p' and 'a2_p' */
|
||||
res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1);
|
||||
res_p->y1 = LV_MATH_MAX(a1_p->y1, a2_p->y1);
|
||||
res_p->x2 = LV_MATH_MIN(a1_p->x2, a2_p->x2);
|
||||
res_p->y2 = LV_MATH_MIN(a1_p->y2, a2_p->y2);
|
||||
|
||||
/*If x1 or y1 greater then x2 or y2 then the areas union is empty*/
|
||||
bool union_ok = true;
|
||||
if((res_p->x1 > res_p->x2) || (res_p->y1 > res_p->y2)) {
|
||||
union_ok = false;
|
||||
}
|
||||
|
||||
return union_ok;
|
||||
}
|
||||
/**
|
||||
* Join two areas into a third which involves the other two
|
||||
* @param res_p pointer to an area, the result will be stored here
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
*/
|
||||
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
a_res_p->x1 = LV_MATH_MIN(a1_p->x1, a2_p->x1);
|
||||
a_res_p->y1 = LV_MATH_MIN(a1_p->y1, a2_p->y1);
|
||||
a_res_p->x2 = LV_MATH_MAX(a1_p->x2, a2_p->x2);
|
||||
a_res_p->y2 = LV_MATH_MAX(a1_p->y2, a2_p->y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a point is on an area
|
||||
* @param a_p pointer to an area
|
||||
* @param p_p pointer to a point
|
||||
* @return false:the point is out of the area
|
||||
*/
|
||||
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
|
||||
{
|
||||
bool is_on = false;
|
||||
|
||||
if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) && ((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {
|
||||
is_on = true;
|
||||
}
|
||||
|
||||
return is_on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two area has common parts
|
||||
* @param a1_p pointer to an area.
|
||||
* @param a2_p pointer to an other area
|
||||
* @return false: a1_p and a2_p has no common parts
|
||||
*/
|
||||
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
|
||||
{
|
||||
if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) && (a1_p->y2 >= a2_p->y1)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an area is fully on an other
|
||||
* @param ain_p pointer to an area which could be in 'aholder_p'
|
||||
* @param aholder pointer to an area which could involve 'ain_p'
|
||||
* @return
|
||||
*/
|
||||
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)
|
||||
{
|
||||
bool is_in = false;
|
||||
|
||||
if(ain_p->x1 >= aholder_p->x1 && ain_p->y1 >= aholder_p->y1 && ain_p->x2 <= aholder_p->x2 &&
|
||||
ain_p->y2 <= aholder_p->y2) {
|
||||
is_in = true;
|
||||
}
|
||||
|
||||
return is_in;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
176
extended-setup/components/lvgl/src/lv_misc/lv_area.h
Normal file
176
extended-setup/components/lvgl/src/lv_misc/lv_area.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @file lv_area.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_AREA_H
|
||||
#define LV_AREA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*To avoid overflow don't let the max ranges (reduce with 1000) */
|
||||
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
|
||||
#define LV_COORD_MIN (-LV_COORD_MAX)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Represents a point on the screen.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
} lv_point_t;
|
||||
|
||||
/** Represents an area of the screen. */
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t x1;
|
||||
lv_coord_t y1;
|
||||
lv_coord_t x2;
|
||||
lv_coord_t y2;
|
||||
} lv_area_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an area
|
||||
* @param area_p pointer to an area
|
||||
* @param x1 left coordinate of the area
|
||||
* @param y1 top coordinate of the area
|
||||
* @param x2 right coordinate of the area
|
||||
* @param y2 bottom coordinate of the area
|
||||
*/
|
||||
void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2);
|
||||
|
||||
/**
|
||||
* Copy an area
|
||||
* @param dest pointer to the destination area
|
||||
* @param src pointer to the source area
|
||||
*/
|
||||
inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(lv_area_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of an area
|
||||
* @param area_p pointer to an area
|
||||
* @return the width of the area (if x1 == x2 -> width = 1)
|
||||
*/
|
||||
static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p)
|
||||
{
|
||||
return area_p->x2 - area_p->x1 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of an area
|
||||
* @param area_p pointer to an area
|
||||
* @return the height of the area (if y1 == y2 -> height = 1)
|
||||
*/
|
||||
static inline lv_coord_t lv_area_get_height(const lv_area_t * area_p)
|
||||
{
|
||||
return area_p->y2 - area_p->y1 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width of an area
|
||||
* @param area_p pointer to an area
|
||||
* @param w the new width of the area (w == 1 makes x1 == x2)
|
||||
*/
|
||||
void lv_area_set_width(lv_area_t * area_p, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an area
|
||||
* @param area_p pointer to an area
|
||||
* @param h the new height of the area (h == 1 makes y1 == y2)
|
||||
*/
|
||||
void lv_area_set_height(lv_area_t * area_p, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the position of an area (width and height will be kept)
|
||||
* @param area_p pointer to an area
|
||||
* @param x the new x coordinate of the area
|
||||
* @param y the new y coordinate of the area
|
||||
*/
|
||||
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Return with area of an area (x * y)
|
||||
* @param area_p pointer to an area
|
||||
* @return size of area
|
||||
*/
|
||||
uint32_t lv_area_get_size(const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the common parts of two areas
|
||||
* @param res_p pointer to an area, the result will be stored her
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
* @return false: the two area has NO common parts, res_p is invalid
|
||||
*/
|
||||
bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Join two areas into a third which involves the other two
|
||||
* @param res_p pointer to an area, the result will be stored here
|
||||
* @param a1_p pointer to the first area
|
||||
* @param a2_p pointer to the second area
|
||||
*/
|
||||
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Check if a point is on an area
|
||||
* @param a_p pointer to an area
|
||||
* @param p_p pointer to a point
|
||||
* @return false:the point is out of the area
|
||||
*/
|
||||
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p);
|
||||
|
||||
/**
|
||||
* Check if two area has common parts
|
||||
* @param a1_p pointer to an area.
|
||||
* @param a2_p pointer to an other area
|
||||
* @return false: a1_p and a2_p has no common parts
|
||||
*/
|
||||
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
|
||||
/**
|
||||
* Check if an area is fully on an other
|
||||
* @param ain_p pointer to an area which could be on aholder_p
|
||||
* @param aholder pointer to an area which could involve ain_p
|
||||
* @return
|
||||
*/
|
||||
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
75
extended-setup/components/lvgl/src/lv_misc/lv_async.c
Normal file
75
extended-setup/components/lvgl/src/lv_misc/lv_async.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lv_async.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_async.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_async_task_cb(lv_task_t *task);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
|
||||
{
|
||||
/*Allocate an info structure */
|
||||
lv_async_info_t *info = lv_mem_alloc(sizeof(lv_async_info_t));
|
||||
|
||||
if(info == NULL)
|
||||
return LV_RES_INV;
|
||||
|
||||
/* Create a new task */
|
||||
/* Use highest priority so that it will run before a refresh */
|
||||
lv_task_t *task = lv_task_create(lv_async_task_cb, 0, LV_TASK_PRIO_HIGHEST, info);
|
||||
|
||||
if(task == NULL) {
|
||||
lv_mem_free(info);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
info->cb = async_xcb;
|
||||
info->user_data = user_data;
|
||||
|
||||
/* Set the task's user data */
|
||||
task->user_data = info;
|
||||
lv_task_once(task);
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_async_task_cb(lv_task_t *task)
|
||||
{
|
||||
lv_async_info_t *info = (lv_async_info_t *)task->user_data;
|
||||
|
||||
info->cb(info->user_data);
|
||||
|
||||
lv_mem_free(info);
|
||||
}
|
||||
62
extended-setup/components/lvgl/src/lv_misc/lv_async.h
Normal file
62
extended-setup/components/lvgl/src/lv_misc/lv_async.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file lv_async.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ASYNC_H
|
||||
#define LV_ASYNC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_task.h"
|
||||
#include "lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Type for async callback.
|
||||
*/
|
||||
typedef void (*lv_async_cb_t)(void *);
|
||||
|
||||
typedef struct _lv_async_info_t {
|
||||
lv_async_cb_t cb;
|
||||
void *user_data;
|
||||
} lv_async_info_t;
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Call an asynchronous function the next time lv_task_handler() is run. This function is likely to return
|
||||
* **before** the call actually happens!
|
||||
* @param task_xcb a callback which is the task itself.
|
||||
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
|
||||
* the `func_name(object, callback, ...)` convention)
|
||||
* @param user_data custom parameter
|
||||
*/
|
||||
lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
||||
79
extended-setup/components/lvgl/src/lv_misc/lv_circ.c
Normal file
79
extended-setup/components/lvgl/src/lv_misc/lv_circ.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file lv_circ.c
|
||||
* Circle drawing algorithm (with Bresenham)
|
||||
* Only a 1/8 circle is calculated. Use CIRC_OCT1_X, CIRC_OCT1_Y macros to get
|
||||
* the other octets.
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_circ.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the circle drawing
|
||||
* @param c pointer to a point. The coordinates will be calculated here
|
||||
* @param tmp point to a variable. It will store temporary data
|
||||
* @param radius radius of the circle
|
||||
*/
|
||||
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius)
|
||||
{
|
||||
c->x = radius;
|
||||
c->y = 0;
|
||||
*tmp = 1 - radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the circle drawing is ready or not
|
||||
* @param c same as in circ_init
|
||||
* @return true if the circle is not ready yet
|
||||
*/
|
||||
bool lv_circ_cont(lv_point_t * c)
|
||||
{
|
||||
return c->y <= c->x ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next point from the circle
|
||||
* @param c same as in circ_init. The next point stored here.
|
||||
* @param tmp same as in circ_init.
|
||||
*/
|
||||
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp)
|
||||
{
|
||||
c->y++;
|
||||
|
||||
if(*tmp <= 0) {
|
||||
(*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1
|
||||
} else {
|
||||
c->x--;
|
||||
(*tmp) += 2 * (c->y - c->x) + 1; // Change for y -> y+1, x -> x-1
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
77
extended-setup/components/lvgl/src/lv_misc/lv_circ.h
Normal file
77
extended-setup/components/lvgl/src/lv_misc/lv_circ.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file lv_circ.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_CIRC_H
|
||||
#define LV_CIRC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_CIRC_OCT1_X(p) (p.x)
|
||||
#define LV_CIRC_OCT1_Y(p) (p.y)
|
||||
#define LV_CIRC_OCT2_X(p) (p.y)
|
||||
#define LV_CIRC_OCT2_Y(p) (p.x)
|
||||
#define LV_CIRC_OCT3_X(p) (-p.y)
|
||||
#define LV_CIRC_OCT3_Y(p) (p.x)
|
||||
#define LV_CIRC_OCT4_X(p) (-p.x)
|
||||
#define LV_CIRC_OCT4_Y(p) (p.y)
|
||||
#define LV_CIRC_OCT5_X(p) (-p.x)
|
||||
#define LV_CIRC_OCT5_Y(p) (-p.y)
|
||||
#define LV_CIRC_OCT6_X(p) (-p.y)
|
||||
#define LV_CIRC_OCT6_Y(p) (-p.x)
|
||||
#define LV_CIRC_OCT7_X(p) (p.y)
|
||||
#define LV_CIRC_OCT7_Y(p) (-p.x)
|
||||
#define LV_CIRC_OCT8_X(p) (p.x)
|
||||
#define LV_CIRC_OCT8_Y(p) (-p.y)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the circle drawing
|
||||
* @param c pointer to a point. The coordinates will be calculated here
|
||||
* @param tmp point to a variable. It will store temporary data
|
||||
* @param radius radius of the circle
|
||||
*/
|
||||
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius);
|
||||
|
||||
/**
|
||||
* Test the circle drawing is ready or not
|
||||
* @param c same as in circ_init
|
||||
* @return true if the circle is not ready yet
|
||||
*/
|
||||
bool lv_circ_cont(lv_point_t * c);
|
||||
|
||||
/**
|
||||
* Get the next point from the circle
|
||||
* @param c same as in circ_init. The next point stored here.
|
||||
* @param tmp same as in circ_init.
|
||||
*/
|
||||
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user