mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
Merge branch 'beta'
This commit is contained in:
commit
42f040f885
@ -63,7 +63,7 @@ See the [example HAL](https://github.com/littlevgl/hal) repository!
|
||||
* your_systick_init();
|
||||
* your_disp_init();
|
||||
* your_indev_init();
|
||||
* **lvgl_init()**;
|
||||
* **lv_init()**;
|
||||
10. To **test** create a label: `lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);`
|
||||
11. In the main *while(1)* call `ptask_handler();` and make a few milliseconds delay (e.g. `your_delay_ms(5);`)
|
||||
12. Compile the code and load it to your embedded hardware
|
||||
|
@ -146,6 +146,14 @@ const lv_app_dsc_t * lv_app_benchmark_init(void)
|
||||
static void my_app_run(lv_app_inst_t * app, void * conf)
|
||||
{
|
||||
/*Initialize the application*/
|
||||
my_app_data_t * ad = app->app_data;
|
||||
ad->opa = 0;
|
||||
ad->recolor = 0;
|
||||
ad->shdw = 0;
|
||||
ad->upscalse = 0;
|
||||
ad->wp = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,18 +17,19 @@
|
||||
#define LV_HOR_RES (320 * LV_DOWNSCALE)
|
||||
#define LV_VER_RES (240 * LV_DOWNSCALE)
|
||||
#define LV_DPI (80 * LV_DOWNSCALE)
|
||||
/* Enable anti-aliasing
|
||||
* If enabled everything will half-sized
|
||||
* Use LV_DOWNSCALE to compensate he down scaling effect of anti-aliasing*/
|
||||
#define LV_ANTIALIAS 1
|
||||
#define LV_DOWNSCALE (1 << LV_ANTIALIAS) /*Set the downscaling value*/
|
||||
|
||||
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
|
||||
#define LV_VDB_SIZE (LV_HOR_RES * 30)
|
||||
|
||||
/* Enable antialaiassing
|
||||
* If enabled everything will half-sized
|
||||
* Use LV_DOWNSCALE to compensate
|
||||
* the down scaling effect of antialiassing*/
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/*Set the downscaling value*/
|
||||
#define LV_DOWNSCALE (1 << LV_ANTIALIAS)
|
||||
#define LV_VDB_SIZE (LV_HOR_RES * LV_VER_RES / 20)
|
||||
#if LV_VDB_SIZE
|
||||
/* Double virtual buffering
|
||||
* One for rendering another to transfer former rendered image to frame buffer in the background*/
|
||||
#define LV_VDB_DOUBLE 0
|
||||
#endif
|
||||
|
||||
#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/
|
||||
#define LV_INV_FIFO_SIZE 32 /*The average number of objects on a screen */
|
||||
@ -47,9 +48,11 @@
|
||||
/*lv_obj (base object) settings*/
|
||||
#define LV_OBJ_FREE_NUM 1 /*Enable the free number attribute*/
|
||||
#define LV_OBJ_FREE_P 1 /*Enable the free pointer attribute*/
|
||||
#define LV_OBJ_GROUP 1 /*Enable object groups*/
|
||||
|
||||
/*Others*/
|
||||
#define LV_COLOR_TRANSP COLOR_LIME
|
||||
#define LV_COLOR_TRANSP COLOR_LIME /*This could mean transparent pixel*/
|
||||
#define USE_LV_EXAMPLE 1 /*Enable examples (lvgl/lv_examples/). Disable to save memory*/
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
@ -145,6 +148,9 @@
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, lv_img)*/
|
||||
#define USE_LV_LIST 1
|
||||
#if USE_LV_LIST != 0
|
||||
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label)*/
|
||||
#define USE_LV_DDLIST 1
|
||||
|
@ -123,8 +123,7 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
|
||||
cord_t map_width = area_get_width(&vdb_rel_a);
|
||||
if(color_map[0].full != color.full || last_width != map_width) {
|
||||
uint16_t i;
|
||||
|
||||
for(i =0; i < map_width; i++) {
|
||||
for(i = 0; i < map_width; i++) {
|
||||
color_map[i].full = color.full;
|
||||
}
|
||||
|
||||
@ -133,7 +132,6 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
|
||||
cord_t row;
|
||||
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
|
||||
disp_color_cpy(&vdb_buf_tmp[vdb_rel_a.x1], color_map, map_width, opa);
|
||||
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
#endif
|
||||
|
67
lv_examples/1_1_hello_world/lv_ex_hello_world.c
Normal file
67
lv_examples/1_1_hello_world/lv_ex_hello_world.c
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file lv_ex_hello_world.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Greetings,
|
||||
* this is the first example in the tutorial hence this is the most simple one.
|
||||
* It only creates a Label, set its text, and align to the middle.
|
||||
*
|
||||
* Be sure in lv_conf.h LV_APP_ENEBLE is 0 (just for simplicity)
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_hello_world.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple 'Hello world!' label
|
||||
*/
|
||||
void lv_ex_hello_world(void)
|
||||
{
|
||||
/*Create a Label on the current screen*/
|
||||
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
|
||||
|
||||
/*Modify the Label's text*/
|
||||
lv_label_set_text(label1, "Hello world!");
|
||||
|
||||
/* Align the Label to the center
|
||||
* NULL means align on parent (which is the screen now)
|
||||
* 0, 0 at the and means an x, y offset after alignment*/
|
||||
lv_obj_align_us(label1, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
42
lv_examples/1_1_hello_world/lv_ex_hello_world.h
Normal file
42
lv_examples/1_1_hello_world/lv_ex_hello_world.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_hello_world.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_HELLO_WORLD_H
|
||||
#define LV_EX_HELLO_WORLD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_hello_world(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HELLO_WORLD_H*/
|
BIN
lv_examples/1_1_hello_world/lv_ex_hello_world.png
Normal file
BIN
lv_examples/1_1_hello_world/lv_ex_hello_world.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
218
lv_examples/1_2_objects/lv_ex_objects.c
Normal file
218
lv_examples/1_2_objects/lv_ex_objects.c
Normal file
@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @file lv_hello_world.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The basic building blocks (components or widgets) in LittlevGL are the graphical objects.
|
||||
* For example:
|
||||
* - Buttons
|
||||
* - Labels
|
||||
* - Charts
|
||||
* - Sliders etc
|
||||
*
|
||||
* In this part you can learn the basics of the objects like creating, positioning, sizing etc.
|
||||
* You will also meet some different object types and their attributes.
|
||||
*
|
||||
* Regardless to the object type the 'lv_obj_t' variable type is used stores the objects
|
||||
* and you can refer to an object with an lv_obj_t pointer (lv_obj_t *)
|
||||
*
|
||||
* INHERITANCE
|
||||
* -------------
|
||||
* Similarly to object oriented languages some kind of inheritance is used
|
||||
* among the object types.
|
||||
*
|
||||
* Every object is derived from the 'Basic object'. (lv_obj)
|
||||
*
|
||||
* The types are backward compatible which means a type can use all the ancestor
|
||||
* attributes/functions too.
|
||||
*
|
||||
* For example a 'Button' is derived from 'Container' which is derived from 'Basic objects'.
|
||||
* Therefore a button can use container attributes like automatically fit size to the content.
|
||||
*
|
||||
* PARENT-CHILD
|
||||
* -------------
|
||||
* A parent can be considered as the container of its children.
|
||||
* Every object has exactly one parent object (except screens).
|
||||
* A parent can have unlimited number of children.
|
||||
* There is no limitation for the type of the parent.
|
||||
*
|
||||
* The children are visible only on their parent. The parts outside will be cropped (not displayed)
|
||||
*
|
||||
* If the parent is moved the children will be moved with it.
|
||||
*
|
||||
* The earlier created object (and its children) will drawn earlier.
|
||||
* Using this layers can be built.
|
||||
*
|
||||
* LEARN MORE
|
||||
* -------------
|
||||
* - General overview: http://www.gl.littlev.hu/objects
|
||||
* - Detailed description of types: http://www.gl.littlev.hu/object-types
|
||||
*
|
||||
* NOTES
|
||||
* -------------
|
||||
* - Be sure 'LV_OBJ_FREE_P' is enabled in 'lv_conf.h'
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_objects.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the Object usage example
|
||||
*/
|
||||
void lv_ex_objects(void)
|
||||
{
|
||||
|
||||
/********************
|
||||
* CREATE A SCREEN
|
||||
*******************/
|
||||
|
||||
/* Create a new screen and load it
|
||||
* Screen can be created from any type object
|
||||
* Now a Page is used which is an objects with scrollable content*/
|
||||
lv_obj_t * scr = lv_page_create(NULL, NULL);
|
||||
lv_scr_load(scr);
|
||||
|
||||
|
||||
/****************
|
||||
* ADD A TITLE
|
||||
****************/
|
||||
lv_obj_t * label = lv_label_create(scr, NULL); /*First parameters (scr) is the parent*/
|
||||
lv_label_set_text(label, "Object usage demo"); /*Set the text*/
|
||||
lv_obj_set_x(label, 50); /*Labels are inherited from Basic object so 'lv_obj_...' functions can be used*/
|
||||
|
||||
|
||||
/********************
|
||||
* CREATE TWO BUTTONS
|
||||
********************/
|
||||
|
||||
/*Create a button*/
|
||||
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL); /*Create a button on the currently loaded screen*/
|
||||
lv_btn_set_rel_action(btn1, btn_rel_action); /*Set function to call when the button is released*/
|
||||
lv_obj_align(btn1, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the label*/
|
||||
label = lv_label_create(btn1, NULL); /*Create a label on the button (the 'label' variable can be reused)*/
|
||||
lv_label_set_text(label, "Button 1");
|
||||
|
||||
/*Copy the previous button*/
|
||||
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), btn1); /*Second parameter is an object to copy*/
|
||||
lv_obj_align(btn2, btn1, LV_ALIGN_OUT_RIGHT_MID, 50, 0);/*Align next to the prev. button.*/
|
||||
label = lv_label_create(btn2, NULL); /*Create a label on the button*/
|
||||
lv_label_set_text(label, "Button 2");
|
||||
|
||||
|
||||
/****************
|
||||
* ADD A SLIDER
|
||||
****************/
|
||||
|
||||
/*Add a slider (inheritance: lv_obj -> lv_bar -> lv_slider)*/
|
||||
lv_obj_t * slider = lv_slider_create(scr, NULL); /*Create a slider*/
|
||||
lv_obj_set_size(slider, lv_obj_get_width(lv_scr_act()) / 3, LV_DPI / 3); /*Set the size*/
|
||||
lv_obj_align(slider, btn1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the first button*/
|
||||
lv_bar_set_value(slider, 30); /*Slider is a 'bar' so set its value like a 'bar'*/
|
||||
|
||||
|
||||
/***********************
|
||||
* ADD A DROP DOWN LIST
|
||||
************************/
|
||||
|
||||
lv_obj_t * ddlist = lv_ddlist_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(ddlist, slider, LV_ALIGN_OUT_RIGHT_TOP, 20, 0); /*Align next to the slider*/
|
||||
lv_obj_set_free_p(ddlist, slider); /*Save the pointer of the slider in the ddlist (used in 'ddlist_action()')*/
|
||||
lv_ddlist_set_options_str(ddlist, "None\nLittle\nHalf\nA lot\nAll"); /*Set the options*/
|
||||
lv_ddlist_set_action(ddlist, ddlist_action); /*Set function to call on new option choose*/
|
||||
lv_obj_set_top(ddlist, true); /*Enable the drop down list always be on the top*/
|
||||
|
||||
|
||||
/****************
|
||||
* CREATE A CHART
|
||||
****************/
|
||||
lv_obj_t * chart = lv_chart_create(lv_scr_act(), NULL); /*Craete the chart*/
|
||||
lv_obj_set_size(chart, lv_obj_get_width(scr) / 2, lv_obj_get_width(scr) / 4); /*Set the size*/
|
||||
lv_obj_align(chart, slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the slider*/
|
||||
lv_chart_set_dl_width(chart, 3 * LV_DOWNSCALE); /*Set the line width (LV_DOWNSCALE compensates anti-aliasing if enabled)*/
|
||||
|
||||
/*Add a RED data line and set some points*/
|
||||
lv_chart_dl_t * dl1 = lv_chart_add_data_line(chart, COLOR_RED);
|
||||
lv_chart_set_next(chart, dl1, 10);
|
||||
lv_chart_set_next(chart, dl1, 25);
|
||||
lv_chart_set_next(chart, dl1, 45);
|
||||
lv_chart_set_next(chart, dl1, 80);
|
||||
|
||||
/*Add a BLUE data line and set some points*/
|
||||
lv_chart_dl_t * dl2 = lv_chart_add_data_line(chart, COLOR_MAKE(0x40, 0x70, 0xC0));
|
||||
lv_chart_set_next(chart, dl2, 10);
|
||||
lv_chart_set_next(chart, dl2, 25);
|
||||
lv_chart_set_next(chart, dl2, 45);
|
||||
lv_chart_set_next(chart, dl2, 80);
|
||||
lv_chart_set_next(chart, dl2, 75);
|
||||
lv_chart_set_next(chart, dl2, 505);
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Called when a button is released
|
||||
* @param btn pointer to the released button
|
||||
* @param dispi pointer to caller display input (e.g. touchpad)
|
||||
* @return LV_ACTION_RES_OK because the object is not deleted in this function
|
||||
*/
|
||||
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*Increase the button width*/
|
||||
cord_t width = lv_obj_get_width(btn);
|
||||
lv_obj_set_width(btn, width + 20);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new option is chosen in the drop down list
|
||||
* @param ddlist pointer to the drop down list
|
||||
* @param dispi pointer to caller display input (e.g. touchpad)
|
||||
* @return LV_ACTION_RES_OK because the object is not deleted in this function
|
||||
*/
|
||||
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi)
|
||||
{
|
||||
uint16_t opt = lv_ddlist_get_selected(ddlist); /*Get the id of selected option*/
|
||||
|
||||
lv_obj_t * slider = lv_obj_get_free_p(ddlist); /*Get the saved slider*/
|
||||
lv_bar_set_value(slider, (opt * 100) / 4); /*Modify the slider value according to the selection*/
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
42
lv_examples/1_2_objects/lv_ex_objects.h
Normal file
42
lv_examples/1_2_objects/lv_ex_objects.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_objects.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_OBJECTS_H
|
||||
#define LV_EX_OBJECTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_objects(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_USAGE_H*/
|
BIN
lv_examples/1_2_objects/lv_ex_objects.png
Normal file
BIN
lv_examples/1_2_objects/lv_ex_objects.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
161
lv_examples/1_3_styles/lv_ex_styles.c
Normal file
161
lv_examples/1_3_styles/lv_ex_styles.c
Normal file
@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @file lv_ex_styles.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* You can modify the appearance of the graphical objects with styles.
|
||||
* A style is simple 'lv_style_t' variable.
|
||||
* Objects save the address of this variable so it has to be 'static or 'global'.
|
||||
*
|
||||
* A style contains various attributes to describe rectangle, image or text like
|
||||
* objects at same time. To know which attribute is used by an object see:
|
||||
* http://www.gl.littlev.hu/object-types
|
||||
*
|
||||
* To set a new style for an object use: 'lv_obj_set_style(obj, &style);
|
||||
* If NULL is set as style then the object will inherit the parents style.
|
||||
* For example is you create a style for button the label appearance can be defined there as well.
|
||||
*
|
||||
* You can use built-in styles. 'lv_style_get(LV_STYLE_... , ©)' will give you a pointer to built in style
|
||||
* and copy it to variable (second parameter) if it is not NULL.
|
||||
* By default the objects use the built-in styles.
|
||||
* The built-in styles can be modified in run time to give a new default skin to your GUI.
|
||||
*
|
||||
* Learn more here: http://www.gl.littlev.hu/objects#style
|
||||
* */
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_styles.h"
|
||||
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple 'Hello world!' label
|
||||
*/
|
||||
void lv_ex_styles(void)
|
||||
{
|
||||
|
||||
/****************************************
|
||||
* BASE OBJECT + LABEL WITH DEFAULT STYLE
|
||||
****************************************/
|
||||
|
||||
lv_obj_t * obj1;
|
||||
obj1 = lv_obj_create(lv_scr_act(), NULL); /*Create a simple objects*/
|
||||
lv_obj_set_pos(obj1, 10, 10);
|
||||
lv_obj_t * label = lv_label_create(obj1, NULL);
|
||||
|
||||
/*Add a label to the object*/
|
||||
lv_label_set_text(label, "Default");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/****************************************
|
||||
* BASE OBJECT WITH PRETTY COLOR STYLE
|
||||
****************************************/
|
||||
|
||||
lv_obj_t * obj2;
|
||||
obj2 = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(obj2, obj1, LV_ALIGN_OUT_RIGHT_MID, 20, 0); /*Align next to the previous object*/
|
||||
lv_obj_set_style(obj2, lv_style_get(LV_STYLE_PRETTY_COLOR, NULL)); /*Set built in style*/
|
||||
label = lv_label_create(obj2, NULL);
|
||||
|
||||
/* Add a label to the object.
|
||||
* Labels by default inherit the parent's style */
|
||||
lv_label_set_text(label, "Pretty\ncolor");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/*****************************
|
||||
* BASE OBJECT WITH NEW STYLE
|
||||
*****************************/
|
||||
|
||||
/* Create a new style */
|
||||
static lv_style_t style_new; /*Styles can't be local variables*/
|
||||
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_new); /*Copy a built-in style as a starting point*/
|
||||
style_new.radius = LV_RADIUS_CIRCLE; /*Fully round corners*/
|
||||
style_new.swidth = 8; /*8 px shadow*/
|
||||
style_new.bwidth = 2; /*2 px border width*/
|
||||
style_new.mcolor = COLOR_WHITE; /*White main color*/
|
||||
style_new.gcolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_40); /*light blue gradient color*/
|
||||
style_new.scolor = COLOR_MAKE(0xa0, 0xa0, 0xa0); /*Light gray shadow color*/
|
||||
style_new.ccolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_90); /*Blue content color (text color)*/
|
||||
style_new.letter_space = 10; /*10 px letter space*/
|
||||
style_new.txt_align = LV_TXT_ALIGN_MID; /*Middel text align*/
|
||||
|
||||
/*Create a base object and apply the new style*/
|
||||
lv_obj_t * obj3;
|
||||
obj3 = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(obj3, obj2, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
|
||||
lv_obj_set_style(obj3, &style_new);
|
||||
|
||||
/* Add a label to the object.
|
||||
* Labels by default inherit the parent's style */
|
||||
label = lv_label_create(obj3, NULL);
|
||||
lv_label_set_text(label, "New\nstyle");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
|
||||
/************************
|
||||
* CREATE A STYLED LED
|
||||
***********************/
|
||||
|
||||
/*Create a style for the LED*/
|
||||
static lv_style_t style_led;
|
||||
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_led);
|
||||
style_led.swidth = 15;
|
||||
style_led.radius = LV_RADIUS_CIRCLE;
|
||||
style_led.bwidth = 3;
|
||||
style_led.bopa = OPA_30;
|
||||
style_led.mcolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
|
||||
style_led.gcolor = COLOR_MAKE(0x50, 0x07, 0x02);
|
||||
style_led.bcolor = COLOR_MAKE(0xfa, 0x0f, 0x00);
|
||||
style_led.scolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
|
||||
|
||||
/*Create a LED and switch it ON*/
|
||||
lv_obj_t * led1 = lv_led_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(led1, &style_led);
|
||||
lv_obj_align_us(led1, obj1, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_on(led1);
|
||||
|
||||
/*Copy the previous LED and set a brightness*/
|
||||
lv_obj_t * led2 = lv_led_create(lv_scr_act(), led1);
|
||||
lv_obj_align_us(led2, obj2, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_set_bright(led2, 190);
|
||||
|
||||
/*Copy the previous LED and switch it OFF*/
|
||||
lv_obj_t * led3 = lv_led_create(lv_scr_act(), led1);
|
||||
lv_obj_align_us(led3, obj3, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_off(led3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
42
lv_examples/1_3_styles/lv_ex_styles.h
Normal file
42
lv_examples/1_3_styles/lv_ex_styles.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file style_usage.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STYLE_USAGE_H
|
||||
#define STYLE_USAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_styles(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HELLO_WORLD_H*/
|
BIN
lv_examples/1_3_styles/lv_ex_styles.png
Normal file
BIN
lv_examples/1_3_styles/lv_ex_styles.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
0
lv_examples/1_4_responsive/lv_ex_responsive.c
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.c
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.h
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.h
Normal file
1
lv_examples/1_5_animations/lv_ex_animations.c
Normal file
1
lv_examples/1_5_animations/lv_ex_animations.c
Normal file
@ -0,0 +1 @@
|
||||
|
0
lv_examples/1_5_animations/lv_ex_animations.h
Normal file
0
lv_examples/1_5_animations/lv_ex_animations.h
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.c
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.c
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.h
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.h
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.c
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.c
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.h
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.h
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.c
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.c
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.h
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.h
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.c
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.c
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.h
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.h
Normal file
328
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.c
Normal file
328
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.c
Normal file
@ -0,0 +1,328 @@
|
||||
/**
|
||||
* @file lv_ex_encoder_ctrl.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a simple GUI to demonstrate how to control it with an encoder
|
||||
* using 'lv_group'.
|
||||
*
|
||||
* Be sure in lv_conf.h:
|
||||
* - LV_OBJ_GROUP 1 to enable groups
|
||||
* - LV_APP_ENABLE 0 to disable applications because they might bother now
|
||||
*
|
||||
* lv_group:
|
||||
* - you can create groups and add object to them
|
||||
* - it can be a focused object within a group
|
||||
* - the style of the focused object will be automatically modified
|
||||
* - different style modifier functions can be applied in each groups
|
||||
* - you can focus on the next or previous object (lv_group_focus_next/prev)
|
||||
* - letters can be sent to the focused object to do something (lv_group_send):
|
||||
* - LV_GROUP_KEY_RIGHT/UP: increment action in the object
|
||||
* - LV_GROUP_KEY_LEFT/DOWN: decrement action in the object
|
||||
* - LV_GROUP_KEY_ENTER: ok or select action in the object
|
||||
* - LV_GROUP_KEY_ESC: close or back action action in the object
|
||||
* - or any character for example to a text area
|
||||
*
|
||||
* The encoder is replaced by 4 button on the screen:
|
||||
* - [>] Next (lv_group_focus_next): focus on the next object in the group (simulates encoder press)
|
||||
* - [+] IncrementNext (LV_GROUP_KEY_RIGHT): increment signal to the object (simulates rotate right)
|
||||
* - [-] DecrementNext (LV_GROUP_KEY_LEFT): increment signal to the object (simulates rotate left)
|
||||
* - [!] SelectNext (LV_GROUP_KEY_ENTER): Select something (simulates encoder long press or an 'Select' button)
|
||||
*/
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_encoder_ctrl.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void gui_create(void);
|
||||
static void enc_create(void);
|
||||
static lv_action_res_t mbox_yes_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t mbox_no_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enable_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_next(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_inc(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_dec(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_sel(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_obj_t * scr; /*The screen for the demo*/
|
||||
static lv_obj_t * btn_enable; /*An enable button*/
|
||||
static lv_style_t style_mbox_bg; /*Black bg. style with opacity*/
|
||||
static lv_group_t * g; /*An Object Group*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple GUI to demonstrate encoder control capability
|
||||
*/
|
||||
void lv_ex_encoder_ctrl(void)
|
||||
{
|
||||
/* Create a Page screen (to make it scrollable)
|
||||
* and use Pretty layout to make the content responsive.
|
||||
* See the 'responsive' example for more information */
|
||||
scr = lv_page_create(NULL, NULL);
|
||||
lv_cont_set_layout(lv_page_get_scrl(scr), LV_CONT_LAYOUT_PRETTY);
|
||||
lv_page_set_sb_mode(scr, LV_PAGE_SB_MODE_AUTO);
|
||||
lv_scr_load(scr);
|
||||
|
||||
/*Create an object group for objects to focus*/
|
||||
g = lv_group_create();
|
||||
|
||||
/* Create a dark plain style for a message box's background*/
|
||||
lv_style_get(LV_STYLE_PLAIN, &style_mbox_bg);
|
||||
style_mbox_bg.mcolor = COLOR_BLACK;
|
||||
style_mbox_bg.gcolor = COLOR_BLACK;
|
||||
style_mbox_bg.opa = OPA_50;
|
||||
|
||||
/*Create a demo GUI*/
|
||||
gui_create();
|
||||
|
||||
/*Create virtual encoder*/
|
||||
enc_create();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a demo GUI
|
||||
*/
|
||||
static void gui_create(void)
|
||||
{
|
||||
/*Create a title*/
|
||||
lv_obj_t * title = lv_label_create(scr, NULL);
|
||||
lv_label_set_text(title, "Encoder control");
|
||||
lv_obj_set_protect(title, LV_PROTECT_FOLLOW); /*Make a line break in the layout*/
|
||||
|
||||
/*Create a drop down list*/
|
||||
lv_obj_t * ddlist = lv_ddlist_create(scr, NULL);
|
||||
lv_ddlist_set_options_str(ddlist, "Low\nMedium\nHigh");
|
||||
lv_group_add_obj(g, ddlist); /*Add the object to the group*/
|
||||
|
||||
/*Create a holder an check boxes on it*/
|
||||
lv_obj_t * holder = lv_cont_create(scr, NULL); /*Create a transparent holder*/
|
||||
lv_cont_set_fit(holder, true, true);
|
||||
lv_cont_set_layout(holder, LV_CONT_LAYOUT_COL_L);
|
||||
lv_obj_set_style(holder, lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
|
||||
lv_obj_t * cb = lv_cb_create(holder, NULL); /*First check box*/
|
||||
lv_cb_set_text(cb, "Red");
|
||||
lv_group_add_obj(g, cb); /*Add to the group*/
|
||||
|
||||
cb = lv_cb_create(holder, cb); /*Copy the first check box. Automatically added to the same group*/
|
||||
lv_cb_set_text(cb, "Green");
|
||||
|
||||
cb = lv_cb_create(holder, cb); /*Copy the second check box. Automatically added to the same group*/
|
||||
lv_cb_set_text(cb, "Blue");
|
||||
|
||||
/*Create a sliders*/
|
||||
lv_obj_t * slider = lv_slider_create(scr, NULL);
|
||||
lv_obj_set_size_us(slider, 180, 30);
|
||||
lv_bar_set_range(slider, 0, 20);
|
||||
lv_group_add_obj(g, slider); /*Add to the group*/
|
||||
|
||||
/*Create a button*/
|
||||
btn_enable = lv_btn_create(scr, NULL);
|
||||
lv_btn_set_rel_action(btn_enable, enable_action);
|
||||
lv_cont_set_fit(btn_enable, true, true);
|
||||
lv_group_add_obj(g, btn_enable); /*Add to the group*/
|
||||
lv_obj_t * l = lv_label_create(btn_enable, NULL);
|
||||
lv_label_set_text(l, "Enable");
|
||||
lv_obj_set_protect(btn_enable, LV_PROTECT_FOLLOW); /*Make a line break in the layout*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Create virtual encoder using 4 buttons:
|
||||
* - [>] Next: focus on the next object in the group (simulates encoder press)
|
||||
* - [+] Increment: increment signal to the object (simulates rotate right)
|
||||
* - [-] Decrement: increment signal to the object (simulates rotate left)
|
||||
* - [!] Select: Select something (simulates encoder long press or an 'Select' button)
|
||||
*/
|
||||
static void enc_create(void)
|
||||
{
|
||||
/*Next button*/
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL);
|
||||
lv_btn_set_rel_action(btn, enc_next);
|
||||
lv_cont_set_fit(btn, true, true);
|
||||
lv_obj_t * l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, ">");
|
||||
|
||||
/*Increment button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_dec);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "-");
|
||||
|
||||
/*Decrement button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_inc);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "+");
|
||||
|
||||
/*Select button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_sel);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Enable button is released. Show a message box to really enable or not?
|
||||
* @param btn pointer to the Enable button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enable_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*If the butto nsi released the show message box to be sure about the Enable*/
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_REL) {
|
||||
/* Create a dark screen sized bg. with opacity to show
|
||||
* the other objects are not available now*/
|
||||
lv_obj_t * bg = lv_obj_create(scr, NULL);
|
||||
lv_obj_set_protect(bg, LV_PROTECT_PARENT); /*The page screen move it to scrollable area*/
|
||||
lv_obj_set_parent(bg, scr); /*So movi it back ater protected*/
|
||||
lv_obj_set_style(bg, &style_mbox_bg);
|
||||
lv_obj_set_size(bg, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_pos(bg, 0, 0);
|
||||
lv_obj_set_click(bg, false); /*For test disable click there fore buttons under it remain clickable*/
|
||||
|
||||
/*Create a message box*/
|
||||
lv_obj_t * mbox = lv_mbox_create(bg, NULL);
|
||||
lv_mbox_set_text(mbox, "Really Enable the outputs?");
|
||||
lv_group_add_obj(g, mbox); /*Add to he group*/
|
||||
|
||||
/*Add two buttons*/
|
||||
lv_mbox_add_btn(mbox, "Yes", mbox_yes_action);
|
||||
lv_mbox_add_btn(mbox, "No", mbox_no_action);
|
||||
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, - LV_DPI / 2);
|
||||
|
||||
/*Focus on the new message box, can freeze focus on it*/
|
||||
lv_group_focus_obj(mbox);
|
||||
lv_group_focus_freeze(g, true);
|
||||
}
|
||||
/*Disable is not dangerous so just change the button state*/
|
||||
else {
|
||||
lv_btn_set_state(btn_enable, LV_BTN_STATE_REL);
|
||||
}
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the message box's 'Yes' button is released
|
||||
* @param btn pointer to the 'Yes' button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_INV: because the button along with the message box will be deleted
|
||||
*/
|
||||
static lv_action_res_t mbox_yes_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
lv_group_focus_freeze(g, false); /*Release the freeze*/
|
||||
lv_obj_t * mbox = lv_mbox_get_from_btn(btn);
|
||||
lv_obj_del(lv_obj_get_parent(mbox)); /*Delete the black background. (it will delete the mbox too)*/
|
||||
|
||||
/*Mark the enabled state by toggling the button*/
|
||||
lv_btn_set_state(btn_enable, LV_BTN_STATE_TREL);
|
||||
|
||||
/* In a real case you can add some specific actions here
|
||||
* to really enable something */
|
||||
|
||||
return LV_ACTION_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the message box's 'No' button is released
|
||||
* @param btn pointer to the 'No' button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_INV: because the button along with the message box will be deleted
|
||||
*/
|
||||
static lv_action_res_t mbox_no_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
lv_group_focus_freeze(g, false); /*Release the freeze*/
|
||||
lv_obj_t * mbox = lv_mbox_get_from_btn(btn);
|
||||
lv_obj_del(lv_obj_get_parent(mbox)); /*Delete the black background. (it will delete the mbox too)*/
|
||||
|
||||
return LV_ACTION_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Next button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_next(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*Focus on the next object in the group*/
|
||||
lv_group_focus_next(g);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Increment button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_inc(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send RIGHT key when rotate to right.
|
||||
* It will trigger an increment like action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_RIGHT);
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Increment button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_dec(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send LEFT key when rotate to left.
|
||||
* It will trigger a decrement like action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_LEFT);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
/**
|
||||
* Called when the Encoder emulator's Send button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_sel(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send ENTER key.
|
||||
* It will trigger an 'OK' or 'Select' action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_ENTER);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
42
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.h
Normal file
42
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_encoder_ctrl.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_ENCODER_CTRL_H
|
||||
#define LV_EX_ENCODER_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_encoder_ctrl(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*ENCODER_CTRL_H*/
|
BIN
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.png
Normal file
BIN
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.c
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.c
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.h
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.h
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.c
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.c
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.h
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.h
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.c
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.c
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.h
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.h
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.c
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.c
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.h
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.h
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.c
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.c
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.h
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.h
Normal file
41
lv_examples/README.md
Normal file
41
lv_examples/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# EXAMPLES FOR LITTLEV GRAPHICS LIBRARY
|
||||
|
||||
## Introduction
|
||||
In the folders you will find simple hardware independent examples to know the key features of Littlev Graphics Library.
|
||||
The examples are organized in consistent way and can be used as a **Tutorial**.
|
||||
|
||||
Every example consist of least an *example_name.c* and *example_name.h* files. You can load an example in your *main* function with **example_name_init()**. The header file has to be included too.
|
||||
|
||||
You will find **detailed explanation** in the *c* and *h* files.
|
||||
|
||||
The examples can be enabled/disabled in *lv_conf.h* with **USE_LV_EXAMPLES**.
|
||||
|
||||
## 1_x Getting started
|
||||
With examples in this section you can learn the basics from a simple *Hello world* label to a complex full featured GUI with animations and other effects. You will learn about
|
||||
- creating, deleting graphical objects
|
||||
- modify their attributes
|
||||
- change their style
|
||||
- and even creating a new object type
|
||||
|
||||
## 2_x GUI control without Touchpad
|
||||
You can control your GUI not only with Touchpad. The most simple way to put real buttons next to the graphical ones and simulate *touch pad-like press* on the display. An other way is to organize the objects in groups and *focus* on one of objects. Then you can control the object-in-focus with simple character instructions. Or using a cursor and mouse is also possible. So an external control device can be
|
||||
- push buttons
|
||||
- encoders
|
||||
- keyboard
|
||||
- or a mouse
|
||||
|
||||
In this section you will find examples for them!
|
||||
|
||||
## 3_x Applications
|
||||
The applications are high level components to do complex thing with a nice user interface. An application can be for example
|
||||
- WiFi network manager
|
||||
- File system browser
|
||||
- System monitor
|
||||
- Terminal etc.
|
||||
|
||||
Here you will find examples how to run application, and communicate with them.
|
||||
|
||||
## Final words
|
||||
If you also have codes which could be useful for others, please share it via *Pull requests* on *GitHub*!
|
||||
Thank you in advance!
|
||||
|
264
lv_obj/lv_group.c
Normal file
264
lv_obj/lv_group.c
Normal file
@ -0,0 +1,264 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_OBJ_GROUP != 0
|
||||
#include <stddef.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void style_mod_def(lv_style_t * style);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = dm_alloc(sizeof(lv_group_t));
|
||||
ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->style_mod = style_mod_def;
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
|
||||
return 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)
|
||||
{
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = ll_ins_tail(&group->obj_ll);
|
||||
*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(ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_focus_next(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an objectto remove
|
||||
*/
|
||||
void lv_group_rem_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
lv_obj_t ** i;
|
||||
|
||||
LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
ll_rem(&g->obj_ll, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(*g->obj_focus == obj) {
|
||||
g->obj_focus = NULL;
|
||||
lv_group_focus_next(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) return;
|
||||
|
||||
lv_obj_t ** i;
|
||||
|
||||
LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL){
|
||||
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*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)
|
||||
{
|
||||
if(group->frozen != 0) return;
|
||||
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
lv_obj_t ** obj_next;
|
||||
if(group->obj_focus == NULL) obj_next = ll_get_head(&group->obj_ll);
|
||||
else obj_next = ll_get_next(&group->obj_ll, group->obj_focus);
|
||||
|
||||
if(obj_next == NULL) obj_next = ll_get_head(&group->obj_ll);
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
if(group->obj_focus != NULL){
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if(group->frozen != 0) return;
|
||||
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
lv_obj_t ** obj_next;
|
||||
if(group->obj_focus == NULL) obj_next = ll_get_tail(&group->obj_ll);
|
||||
else obj_next = ll_get_prev(&group->obj_ll, group->obj_focus);
|
||||
|
||||
if(obj_next == NULL) obj_next = ll_get_tail(&group->obj_ll);
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
if(group->obj_focus != NULL){
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 control character (use LV_GROUP_KEY_.. to navigate)
|
||||
*/
|
||||
void lv_group_send(lv_group_t * group, char c)
|
||||
{
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return;
|
||||
|
||||
act->signal_f(act, LV_SIGNAL_CONTROLL, &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_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style))
|
||||
{
|
||||
group->style_mod = style_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
lv_style_cpy(&group->style_tmp, style);
|
||||
|
||||
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
|
||||
else style_mod_def(&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(lv_group_t * group)
|
||||
{
|
||||
if(group == NULL) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param style pointer to a style to modify. (Typically &group->style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_def(lv_style_t * style)
|
||||
{
|
||||
/*Make the style a little bit orange*/
|
||||
style->bcolor = COLOR_ORANGE;
|
||||
style->bopa = OPA_COVER;
|
||||
if(style->bwidth == 0 && style->empty == 0) style->bwidth = 2 * LV_DOWNSCALE; /*Add border to not transparent styles*/
|
||||
else style->bwidth = style->bwidth * 2; /*Make the border thicker*/
|
||||
style->mcolor = color_mix(style->mcolor, COLOR_ORANGE, OPA_80);
|
||||
style->gcolor = color_mix(style->gcolor, COLOR_ORANGE, OPA_80);
|
||||
}
|
||||
|
||||
#endif /*LV_OBJ_GROUP != 0*/
|
68
lv_obj/lv_group.h
Normal file
68
lv_obj/lv_group.h
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#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_OBJ_GROUP*/
|
||||
#define LV_GROUP_KEY_UP 17 /*0x11*/
|
||||
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
|
||||
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
|
||||
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
|
||||
#define LV_GROUP_KEY_ESC 33 /*0x1B*/
|
||||
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct
|
||||
{
|
||||
ll_dsc_t obj_ll;
|
||||
lv_obj_t ** obj_focus;
|
||||
void (*style_mod)(lv_style_t * style);
|
||||
lv_style_t style_tmp;
|
||||
uint8_t frozen:1;
|
||||
}lv_group_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_group_t * lv_group_create(void);
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
|
||||
void lv_group_rem_obj(lv_obj_t * obj);
|
||||
void lv_group_focus_obj(lv_obj_t * obj);
|
||||
void lv_group_focus_next(lv_group_t * group);
|
||||
void lv_group_focus_prev(lv_group_t * group);
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
||||
void lv_group_send(lv_group_t * group, char c);
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
|
||||
lv_obj_t * lv_group_get_focused(lv_group_t * group);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_OBJ_GROUP != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
@ -12,8 +12,10 @@
|
||||
#include "lvgl/lv_obj/lv_dispi.h"
|
||||
#include "lvgl/lv_obj/lv_obj.h"
|
||||
#include "lvgl/lv_obj/lv_refr.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "lvgl/lv_app/lv_app.h"
|
||||
#include "lvgl/lv_draw/lv_draw_rbasic.h"
|
||||
#include "lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "hal/indev/indev.h"
|
||||
#include <stdint.h>
|
||||
@ -141,10 +143,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
#if LV_OBJ_FREE_NUM != 0
|
||||
new_obj->free_num = 0;
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_FREE_P != 0
|
||||
new_obj->free_p = NULL;
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
new_obj->group_p = NULL;
|
||||
#endif
|
||||
/*Set attributes*/
|
||||
new_obj->click_en = 0;
|
||||
new_obj->drag_en = 0;
|
||||
@ -187,6 +193,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
#if LV_OBJ_FREE_P != 0
|
||||
new_obj->free_p = NULL;
|
||||
#endif
|
||||
#if LV_OBJ_GROUP != 0
|
||||
new_obj->group_p = NULL;
|
||||
#endif
|
||||
|
||||
/*Set attributes*/
|
||||
new_obj->click_en = 1;
|
||||
@ -198,7 +207,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
|
||||
new_obj->ext = NULL;
|
||||
|
||||
}
|
||||
|
||||
if(copy != NULL) {
|
||||
@ -223,6 +231,13 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
|
||||
new_obj->style_p = copy->style_p;
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/*Add to the same group*/
|
||||
if(copy->group_p != NULL) {
|
||||
lv_group_add_obj(copy->group_p, new_obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy));
|
||||
}
|
||||
|
||||
@ -405,12 +420,14 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
|
||||
old_pos.x = lv_obj_get_x(obj);
|
||||
old_pos.y = lv_obj_get_y(obj);
|
||||
|
||||
lv_obj_t * old_par = obj->par;
|
||||
|
||||
ll_chg_list(&obj->par->child_ll, &parent->child_ll, obj);
|
||||
obj->par = parent;
|
||||
lv_obj_set_pos(obj, old_pos.x, old_pos.y);
|
||||
|
||||
/*Notify the original parent because one of its children is lost*/
|
||||
obj->par->signal_f(obj->par, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
old_par->signal_f(old_par, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
|
||||
/*Notify the new parent about the child*/
|
||||
parent->signal_f(parent, LV_SIGNAL_CHILD_CHG, obj);
|
||||
@ -1234,20 +1251,28 @@ cord_t lv_obj_get_ext_size(lv_obj_t * obj)
|
||||
*/
|
||||
lv_style_t * lv_obj_get_style(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->style_p != NULL) return obj->style_p;
|
||||
else {
|
||||
lv_style_t * style_act = obj->style_p;
|
||||
if(style_act == NULL) {
|
||||
lv_obj_t * par = obj->par;
|
||||
|
||||
while(par != NULL) {
|
||||
if(par->style_p != NULL) {
|
||||
if(par->style_p->glass == 0) return par->style_p;
|
||||
if(par->style_p->glass == 0) {
|
||||
style_act = par->style_p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
par = par->par;
|
||||
}
|
||||
}
|
||||
|
||||
/*Never reach this, at least the screen has to be a style*/
|
||||
return NULL;
|
||||
#if LV_OBJ_GROUP != 0
|
||||
if(obj->group_p != NULL) {
|
||||
if(lv_group_get_focused(obj->group_p) == obj) {
|
||||
style_act = lv_group_mod_style(obj->group_p, style_act);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return style_act;
|
||||
}
|
||||
|
||||
/*-----------------
|
||||
@ -1395,6 +1420,18 @@ void * lv_obj_get_free_p(lv_obj_t * obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**
|
||||
* 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(lv_obj_t * obj)
|
||||
{
|
||||
return obj->group_p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -1471,9 +1508,7 @@ static void lv_style_refr_core(void * style_p, lv_obj_t * obj)
|
||||
lv_obj_t * i;
|
||||
LL_READ(obj->child_ll, i) {
|
||||
if(i->style_p == style_p || style_p == NULL) {
|
||||
lv_obj_inv(i);
|
||||
i->signal_f(i, LV_SIGNAL_STYLE_CHG, NULL);
|
||||
lv_obj_inv(i);
|
||||
lv_child_refr_style(i);
|
||||
}
|
||||
|
||||
lv_style_refr_core(style_p, i);
|
||||
@ -1523,13 +1558,16 @@ static void lv_obj_del_child(lv_obj_t * obj)
|
||||
/*Remove the animations from this object*/
|
||||
anim_del(obj, NULL);
|
||||
|
||||
/*Delete from the group*/
|
||||
#if LV_OBJ_GROUP != 0
|
||||
if(obj->group_p != NULL) lv_group_rem_obj(obj);
|
||||
#endif
|
||||
|
||||
/*Remove the object from parent's children list*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
|
||||
ll_rem(&(par->child_ll), obj);
|
||||
|
||||
/* All children deleted.
|
||||
* Now clean up the object specific data*/
|
||||
/* Clean up the object specific data*/
|
||||
obj->signal_f(obj, LV_SIGNAL_CLEANUP, NULL);
|
||||
|
||||
/*Delete the base objects*/
|
||||
|
@ -72,19 +72,27 @@ typedef bool (* lv_design_f_t) (struct __LV_OBJ_T * obj, const area_t * mask_p,
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/*General signals*/
|
||||
LV_SIGNAL_CLEANUP,
|
||||
LV_SIGNAL_CHILD_CHG,
|
||||
LV_SIGNAL_CORD_CHG,
|
||||
LV_SIGNAL_STYLE_CHG,
|
||||
LV_SIGNAL_REFR_EXT_SIZE,
|
||||
|
||||
/*Display input related*/
|
||||
LV_SIGNAL_PRESSED,
|
||||
LV_SIGNAL_PRESSING,
|
||||
LV_SIGNAL_PRESSING,
|
||||
LV_SIGNAL_PRESS_LOST,
|
||||
LV_SIGNAL_RELEASED,
|
||||
LV_SIGNAL_LONG_PRESS,
|
||||
LV_SIGNAL_LONG_PRESS_REP,
|
||||
LV_SIGNAL_DRAG_BEGIN,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
LV_SIGNAL_CHILD_CHG,
|
||||
LV_SIGNAL_CORD_CHG,
|
||||
LV_SIGNAL_STYLE_CHG,
|
||||
LV_SIGNAL_REFR_EXT_SIZE,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
|
||||
/*Group related*/
|
||||
LV_SIGNAL_FOCUS,
|
||||
LV_SIGNAL_DEFOCUS,
|
||||
LV_SIGNAL_CONTROLL,
|
||||
}lv_signal_t;
|
||||
|
||||
typedef bool (* lv_signal_f_t) (struct __LV_OBJ_T * obj, lv_signal_t sign, void * param);
|
||||
@ -106,6 +114,8 @@ typedef struct __LV_OBJ_T
|
||||
void * free_p; /*Application specific pointer (set it freely)*/
|
||||
#endif
|
||||
|
||||
void * group_p; /*Pointer to the group of the object*/
|
||||
|
||||
/*Attributes and states*/
|
||||
uint8_t click_en :1; /*1: Can be pressed by a display input device*/
|
||||
uint8_t drag_en :1; /*1: Enable the dragging*/
|
||||
@ -159,13 +169,6 @@ typedef enum
|
||||
LV_ALIGN_OUT_RIGHT_BOTTOM,
|
||||
}lv_align_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
color_t color;
|
||||
opa_t opa;
|
||||
}lv_objs_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LV_ANIM_NONE = 0,
|
||||
@ -473,6 +476,7 @@ void lv_obj_set_free_num(lv_obj_t * obj, uint8_t free_num);
|
||||
*/
|
||||
void lv_obj_set_free_p(lv_obj_t * obj, void * free_p);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Animate an object
|
||||
* @param obj pointer to an object to animate
|
||||
@ -665,6 +669,14 @@ uint8_t lv_obj_get_free_num(lv_obj_t * obj);
|
||||
void * lv_obj_get_free_p(lv_obj_t * obj);
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**
|
||||
* 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(lv_obj_t * obj);
|
||||
#endif
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -70,7 +70,6 @@ void lv_refr_init(void)
|
||||
ptask_t* task;
|
||||
task = ptask_create(lv_refr_task, LV_REFR_PERIOD, PTASK_PRIO_MID, NULL);
|
||||
dm_assert(task);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,7 +129,7 @@ void lv_inv_area(const area_t * area_p)
|
||||
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
|
||||
* time_ms: refresh time in [ms]
|
||||
* px_num: not the drawn pixels but the number of affected pixels of the screen
|
||||
* (more pixels are drawn with opacity areas)
|
||||
* (more pixels are drawn because of overlapping objects)
|
||||
*/
|
||||
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
|
||||
{
|
||||
@ -257,15 +256,8 @@ static void lv_refr_area_no_vdb(const area_t * area_p)
|
||||
*/
|
||||
static void lv_refr_area_with_vdb(const area_t * area_p)
|
||||
{
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Always use the full row*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.y1 = area_p->y1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
|
||||
/*Calculate the max row num*/
|
||||
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (vdb_p->area.x2 - vdb_p->area.x1 + 1);
|
||||
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (area_get_width(area_p));
|
||||
if(max_row > area_get_height(area_p)) max_row = area_get_height(area_p);
|
||||
|
||||
/*Round the row number with downscale*/
|
||||
@ -273,20 +265,28 @@ static void lv_refr_area_with_vdb(const area_t * area_p)
|
||||
max_row &= (~0x1);
|
||||
#endif
|
||||
|
||||
/*Refresh all rows*/
|
||||
cord_t row = area_p->y1;
|
||||
|
||||
/*Always use the full row*/
|
||||
cord_t row;
|
||||
cord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= area_p->y2; row += max_row) {
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
vdb_p->area.y1 = row;
|
||||
vdb_p->area.y2 = row + max_row - 1;
|
||||
|
||||
row_last = row + max_row - 1;
|
||||
lv_refr_area_part_vdb(area_p);
|
||||
}
|
||||
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(area_p->y2 != vdb_p->area.y2) {
|
||||
if(area_p->y2 != row_last) {
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
vdb_p->area.y1 = row;
|
||||
vdb_p->area.y2 = area_p->y2;
|
||||
|
||||
|
@ -8,18 +8,31 @@
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#include "lv_style.h"
|
||||
#include "lv_obj.h"
|
||||
#include "misc/mem/dyn_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_STYLE_ANIM_RES 255 /*Animation max in 1024 steps*/
|
||||
#define LV_STYLE_ANIM_SHIFT 8 /*log2(LV_STYLE_ANIM_RES)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> LV_STYLE_ANIM_SHIFT)
|
||||
#define STYLE_ATTR_ANIM(attr, r) if(start->attr != end->attr) act->attr = VAL_PROP(start->attr, end->attr, r)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
const lv_style_t * style_start;
|
||||
const lv_style_t * style_end;
|
||||
lv_style_t * style_anim;
|
||||
}lv_style_anim_dsc_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -229,6 +242,84 @@ void lv_style_cpy(lv_style_t * dest, const lv_style_t * src)
|
||||
memcpy(dest, src, sizeof(lv_style_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
*/
|
||||
void lv_style_anim_create(lv_style_anim_t * anim)
|
||||
{
|
||||
lv_style_anim_dsc_t * dsc;
|
||||
dsc = dm_alloc(sizeof(lv_style_anim_dsc_t));
|
||||
dsc->style_anim = anim->style_anim;
|
||||
dsc->style_start = anim->style_start;
|
||||
dsc->style_end = anim->style_end;
|
||||
|
||||
anim_t a;
|
||||
a.var = (void*)dsc;
|
||||
a.start = 0;
|
||||
a.end = LV_STYLE_ANIM_RES;
|
||||
a.fp = (anim_fp_t)lv_style_aimator;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = anim->end_cb;
|
||||
a.act_time = anim->act_time;
|
||||
a.time = anim->time;
|
||||
a.playback = anim->playback;
|
||||
a.playback_pause = anim->playback_pause;
|
||||
a.repeat = anim->repeat;
|
||||
a.repeat_pause = anim->repeat_pause;
|
||||
|
||||
anim_create(&a);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* 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_STYLE_ANIM_RES
|
||||
*/
|
||||
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_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;
|
||||
|
||||
STYLE_ATTR_ANIM(opa, val);
|
||||
STYLE_ATTR_ANIM(radius, val);
|
||||
STYLE_ATTR_ANIM(bwidth, val);
|
||||
STYLE_ATTR_ANIM(swidth, val);
|
||||
STYLE_ATTR_ANIM(hpad, val);
|
||||
STYLE_ATTR_ANIM(vpad, val);
|
||||
STYLE_ATTR_ANIM(opad, val);
|
||||
STYLE_ATTR_ANIM(line_space, val);
|
||||
STYLE_ATTR_ANIM(letter_space, val);
|
||||
STYLE_ATTR_ANIM(line_width, val);
|
||||
STYLE_ATTR_ANIM(img_recolor, val);
|
||||
|
||||
act->mcolor = color_mix(end->mcolor, start->mcolor, val);
|
||||
act->gcolor = color_mix(end->gcolor, start->gcolor, val);
|
||||
act->bcolor = color_mix(end->bcolor, start->bcolor, val);
|
||||
act->scolor = color_mix(end->scolor, start->scolor, val);
|
||||
act->ccolor = color_mix(end->ccolor, start->ccolor, val);
|
||||
|
||||
|
||||
if(val == 0) {
|
||||
act->empty = start->empty;
|
||||
act->glass = start->glass;
|
||||
act->font = start->font;
|
||||
act->stype = start->stype;
|
||||
act->txt_align = start->txt_align;
|
||||
}
|
||||
|
||||
if(val == LV_STYLE_ANIM_RES) {
|
||||
act->empty = end->empty;
|
||||
act->glass = end->glass;
|
||||
act->font = end->font;
|
||||
act->stype = end->stype;
|
||||
act->txt_align = end->txt_align;
|
||||
}
|
||||
|
||||
lv_style_refr_objs(dsc->style_anim);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ extern "C" {
|
||||
#include "misc/gfx/color.h"
|
||||
#include "misc/gfx/area.h"
|
||||
#include "misc/gfx/font.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@ -83,6 +84,34 @@ typedef enum {
|
||||
}lv_style_name_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
const lv_style_t * style_start; /*Pointer to the starting style*/
|
||||
const lv_style_t * style_end; /*Pointer to the destination style*/
|
||||
lv_style_t * style_anim; /*Pointer to a style to animate*/
|
||||
anim_cb_t end_cb; /*Call it when the animation is ready*/
|
||||
int16_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*/
|
||||
uint8_t playback :1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat :1; /*Repeat the animation infinitely*/
|
||||
}lv_style_anim_t;
|
||||
|
||||
/* Example initialization
|
||||
lv_style_anim_t a;
|
||||
a.style_anim = &style_to_anim;
|
||||
a.style_start = &style_1;
|
||||
a.style_end = &style_2;
|
||||
a.act_time = 0;
|
||||
a.time = 1000;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.end_cb = NULL;
|
||||
lv_style_anim_create(&a);
|
||||
*/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -99,8 +128,20 @@ void lv_style_init (void);
|
||||
*/
|
||||
lv_style_t * lv_style_get(lv_style_name_t style_name, lv_style_t * copy);
|
||||
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_cpy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
*/
|
||||
void lv_style_anim_create(lv_style_anim_t * anim);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -20,7 +20,13 @@
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
typedef enum {
|
||||
LV_VDB_STATE_FREE = 0,
|
||||
LV_VDB_STATE_ACTIVE,
|
||||
LV_VDB_STATE_FLUSH,
|
||||
} lv_vdb_state_t;
|
||||
#endif
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
@ -28,7 +34,12 @@
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
static lv_vdb_t vdb;
|
||||
#else
|
||||
static lv_vdb_t vdb[2];
|
||||
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -39,21 +50,53 @@ static lv_vdb_t vdb;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the vdb variable
|
||||
* @return pointer to the vdb variable
|
||||
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
|
||||
* @return pointer to the 'vdb' variable
|
||||
*/
|
||||
lv_vdb_t * lv_vdb_get(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
return &vdb;
|
||||
#else
|
||||
/*If already there is an active do nothing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) return &vdb[0];
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) return &vdb[1];
|
||||
|
||||
/*Try to allocate a free VDB*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[0] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[0];
|
||||
}
|
||||
|
||||
if(vdb_state[1] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[1] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[1];
|
||||
}
|
||||
|
||||
return NULL; /*There wasn't free VDB (never happen)*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the content of the vdb
|
||||
* Flush the content of the VDB
|
||||
*/
|
||||
void lv_vdb_flush(void)
|
||||
{
|
||||
lv_vdb_t * vdb_act = lv_vdb_get();
|
||||
if(vdb_act == NULL) return;
|
||||
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
/* Wait the pending flush before starting this one
|
||||
* (Don't forget: 'lv_vdb_flush_ready' has to be called when flushing is ready)*/
|
||||
while(vdb_state[0] == LV_VDB_STATE_FLUSH || vdb_state[1] == LV_VDB_STATE_FLUSH);
|
||||
|
||||
/*Turn the active VDB to flushing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) vdb_state[0] = LV_VDB_STATE_FLUSH;
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS == 0
|
||||
disp_map(vdb.area.x1, vdb.area.y1, vdb.area.x2, vdb.area.y2, vdb.buf);
|
||||
disp_map(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
|
||||
#else
|
||||
/* Get the average of 2x2 pixels and put the result back to the VDB
|
||||
* The reading goes much faster then the write back
|
||||
@ -68,12 +111,12 @@ void lv_vdb_flush(void)
|
||||
* */
|
||||
cord_t x;
|
||||
cord_t y;
|
||||
cord_t w = area_get_width(&vdb.area);
|
||||
color_t * in1_buf = vdb.buf; /*Pointer to the first row*/
|
||||
color_t * in2_buf = vdb.buf + w; /*Pointer to the second row*/
|
||||
color_t * out_buf = vdb.buf; /*Store the result here*/
|
||||
for(y = vdb.area.y1; y < vdb.area.y2; y += 2) {
|
||||
for(x = vdb.area.x1; x < vdb.area.x2; x += 2) {
|
||||
cord_t w = area_get_width(&vdb_act->area);
|
||||
color_t * in1_buf = vdb_act->buf; /*Pointer to the first row*/
|
||||
color_t * in2_buf = vdb_act->buf + w; /*Pointer to the second row*/
|
||||
color_t * out_buf = vdb_act->buf; /*Store the result here*/
|
||||
for(y = vdb_act->area.y1; y < vdb_act->area.y2; y += 2) {
|
||||
for(x = vdb_act->area.x1; x < vdb_act->area.x2; x += 2) {
|
||||
|
||||
/*If the pixels are the same do not calculate the average */
|
||||
if(in1_buf->full == (in1_buf + 1)->full &&
|
||||
@ -103,7 +146,19 @@ void lv_vdb_flush(void)
|
||||
|
||||
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
|
||||
* Write out the filtered map to the display*/
|
||||
disp_map(vdb.area.x1 >> 1, vdb.area.y1 >> 1, vdb.area.x2 >> 1, vdb.area.y2 >> 1, vdb.buf);
|
||||
disp_map(vdb_act->area.x1 >> 1, vdb_act->area.y1 >> 1, vdb_act->area.x2 >> 1, vdb_act->area.y2 >> 1, vdb_act->buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* In 'LV_VDB_DOUBLE' mode has to be called when the 'disp_map'
|
||||
* is ready with copying the map to a frame buffer.
|
||||
*/
|
||||
void lv_vdb_flush_ready(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
if(vdb_state[0] == LV_VDB_STATE_FLUSH) vdb_state[0] = LV_VDB_STATE_FREE;
|
||||
if(vdb_state[1] == LV_VDB_STATE_FLUSH) vdb_state[1] = LV_VDB_STATE_FREE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -34,15 +34,13 @@ typedef struct
|
||||
color_t buf[LV_VDB_SIZE];
|
||||
}lv_vdb_t;
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the vdb variable
|
||||
* @return pointer to the vdb variable
|
||||
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
|
||||
* @return pointer to the 'vdb' variable
|
||||
*/
|
||||
lv_vdb_t * lv_vdb_get(void);
|
||||
|
||||
@ -51,6 +49,13 @@ lv_vdb_t * lv_vdb_get(void);
|
||||
*/
|
||||
void lv_vdb_flush(void);
|
||||
|
||||
|
||||
/**
|
||||
* In 'LV_VDB_DOUBLE' mode has to be called when 'disp_map()'
|
||||
* is ready with copying the map to a frame buffer.
|
||||
*/
|
||||
void lv_vdb_flush_ready(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -10,11 +10,11 @@
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_BTN != 0
|
||||
|
||||
#include "lvgl/lv_obj/lv_obj.h"
|
||||
#include "lv_btn.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "misc/gfx/area.h"
|
||||
#include "misc/gfx/color.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "lv_btn.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -185,6 +185,31 @@ bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
if(ext->lpr_rep_action != NULL && state != LV_BTN_STATE_INA) {
|
||||
valid = ext->lpr_rep_action(btn, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
if(lv_btn_get_tgl(btn) != false) {
|
||||
lv_btn_state_t state = lv_btn_get_state(btn);
|
||||
if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
|
||||
else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TPR);
|
||||
else if(state == LV_BTN_STATE_TREL) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(state == LV_BTN_STATE_TPR) lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
}
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,6 +346,50 @@ bool lv_btn_get_tgl(lv_obj_t * btn)
|
||||
return ext->tgl != 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the release action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->rel_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the press action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->pr_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->lpr_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long press repeat action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the long press repeat action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->lpr_rep_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style of a button in a given state
|
||||
* @param btn pointer to a button object
|
||||
|
@ -148,6 +148,32 @@ lv_btn_state_t lv_btn_get_state(lv_obj_t * btn);
|
||||
*/
|
||||
bool lv_btn_get_tgl(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the release action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the press action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the long press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn);
|
||||
/**
|
||||
* Get the long press repeat action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the long press repeat action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn);
|
||||
/**
|
||||
* Get the style of a button in a given state
|
||||
* @param btn pointer to a button object
|
||||
|
@ -10,9 +10,10 @@
|
||||
#if USE_LV_BTNM != 0
|
||||
|
||||
#include "lv_btnm.h"
|
||||
#include "misc/gfx/text.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_obj/lv_refr.h"
|
||||
#include "misc/gfx/text.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@ -29,6 +30,7 @@
|
||||
static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_t mode);
|
||||
static uint8_t lv_btnm_get_width_unit(const char * btn_str);
|
||||
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p);
|
||||
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id);
|
||||
static void lv_btnm_create_btns(lv_obj_t * btnm, const char ** map);
|
||||
|
||||
/**********************
|
||||
@ -155,18 +157,8 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
if(ext->cb != NULL && ext->btn_pr != LV_BTNM_PR_NONE) {
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != ext->btn_pr) {
|
||||
btn_i ++;
|
||||
txt_i ++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
}
|
||||
|
||||
ext->cb(btnm, txt_i);
|
||||
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
|
||||
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED && ext->btn_pr != LV_BTNM_PR_NONE) {
|
||||
@ -181,11 +173,30 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
|
||||
ext->btn_pr = LV_BTNM_PR_NONE;
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
|
||||
ext->btn_pr = LV_BTNM_PR_NONE;
|
||||
lv_obj_inv(btnm);
|
||||
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
ext->btn_pr = 0;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
|
||||
else ext->btn_pr++;
|
||||
if(ext->btn_pr >= ext->btn_cnt - 1) ext->btn_pr = ext->btn_cnt - 1;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
|
||||
if(ext->btn_pr > 0) ext->btn_pr--;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
if(ext->cb != NULL) {
|
||||
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
|
||||
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,7 +416,12 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
|
||||
uint16_t btn_i = 0;
|
||||
uint16_t txt_i = 0;
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++) {
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++, txt_i ++) {
|
||||
/*Search the next valid text in the map*/
|
||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
|
||||
if(ext->map_p[txt_i][1] == '\177') continue;
|
||||
|
||||
lv_obj_get_cords(btnm, &area_btnm);
|
||||
|
||||
area_cpy(&area_tmp, &ext->btn_areas[btn_i]);
|
||||
@ -422,9 +438,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
|
||||
lv_draw_rect(&area_tmp, mask, btn_style);
|
||||
|
||||
/*Search the next valid text in the map*/
|
||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
|
||||
/*Calculate the size of the text*/
|
||||
const font_t * font = btn_style->font;
|
||||
point_t txt_size;
|
||||
@ -438,11 +451,8 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
||||
|
||||
lv_draw_label(&area_tmp, mask, btn_style, ext->map_p[txt_i], TXT_FLAG_NONE, NULL);
|
||||
txt_i ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -486,6 +496,12 @@ static uint8_t lv_btnm_get_width_unit(const char * btn_str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the button id of a button under a given point
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param p a point with absolute coordinates
|
||||
* @return the id of the button or LV_BTNM_PR_NONE.
|
||||
*/
|
||||
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
|
||||
{
|
||||
area_t btnm_cords;
|
||||
@ -510,5 +526,33 @@ static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of a button
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param btn_id button id
|
||||
* @return text id in ext->map_p or LV_BTNM_PR_NONE if 'btn_id' was invalid
|
||||
*/
|
||||
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
|
||||
if(btn_id > ext->btn_cnt) return LV_BTNM_PR_NONE;
|
||||
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != btn_id) {
|
||||
btn_i ++;
|
||||
txt_i ++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
}
|
||||
|
||||
if(btn_i == ext->btn_cnt) return LV_BTNM_PR_NONE;
|
||||
|
||||
return txt_i;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@
|
||||
#if USE_LV_CB != 0
|
||||
|
||||
#include "lv_cb.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@ -23,11 +24,14 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_f_t ancestor_design_f;
|
||||
static lv_design_f_t ancestor_bg_design_f;
|
||||
static lv_design_f_t ancestor_bullet_design_f;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -57,7 +61,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->bullet = NULL;
|
||||
ext->label = NULL;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_cb);
|
||||
if(ancestor_bg_design_f == NULL) ancestor_bg_design_f = lv_obj_get_design_f(new_cb);
|
||||
|
||||
lv_obj_set_signal_f(new_cb, lv_cb_signal);
|
||||
lv_obj_set_design_f(new_cb, lv_cb_design);
|
||||
@ -65,6 +69,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
/*Init the new checkbox object*/
|
||||
if(copy == NULL) {
|
||||
ext->bullet = lv_btn_create(new_cb, NULL);
|
||||
if(ancestor_bullet_design_f == NULL) ancestor_bullet_design_f = lv_obj_get_design_f(ext->bullet);
|
||||
lv_btn_set_styles(new_cb, lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
|
||||
lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
|
||||
lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
@ -88,6 +93,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refr_style(new_cb);
|
||||
}
|
||||
|
||||
lv_obj_set_design_f(ext->bullet, lv_bullet_design);
|
||||
|
||||
return new_cb;
|
||||
}
|
||||
@ -114,11 +121,17 @@ bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
|
||||
if(valid != false) {
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_set_size(ext->bullet, font_get_height(style->font), font_get_height(style->font));
|
||||
}
|
||||
if(sign == LV_SIGNAL_PRESSED ||
|
||||
} else if(sign == LV_SIGNAL_PRESSED ||
|
||||
sign == LV_SIGNAL_RELEASED ||
|
||||
sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
|
||||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP ||
|
||||
c == LV_GROUP_KEY_ENTER) {
|
||||
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,19 +199,62 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
/*Return false if the object is not covers the mask_p area*/
|
||||
return ancestor_design_f(cb, mask, mode);
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {
|
||||
lv_cb_ext_t * cb_ext = lv_obj_get_ext(cb);
|
||||
lv_btn_ext_t * bullet_ext = lv_obj_get_ext(cb_ext->bullet);
|
||||
|
||||
/*Be sure he state of the bullet is the same as the parent button*/
|
||||
/*Be sure the state of the bullet is the same as the parent button*/
|
||||
bullet_ext->state = cb_ext->bg_btn.state;
|
||||
|
||||
return ancestor_design_f(cb, mask, mode);
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
|
||||
} else {
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
}
|
||||
|
||||
/*Draw the object*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the check boxes
|
||||
* @param bullet pointer to an object
|
||||
* @param mask the object will be drawn only in this area
|
||||
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
|
||||
* (return 'true' if yes)
|
||||
* LV_DESIGN_DRAW: draw the object (always return 'true')
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_bullet_design_f(bullet, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/* If the check box is the active in a group and
|
||||
* the background is not visible (transparent or empty)
|
||||
* then activate the style of the bullet*/
|
||||
lv_style_t * style_ori = lv_obj_get_style(bullet);
|
||||
lv_obj_t * bg = lv_obj_get_parent(bullet);
|
||||
lv_style_t * style_page = lv_obj_get_style(bg);
|
||||
lv_group_t * g = lv_obj_get_group(bg);
|
||||
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
|
||||
if(lv_group_get_focused(g) == bg) {
|
||||
lv_style_t * style_mod;
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
bullet->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ancestor_bullet_design_f(bullet, mask, mode);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
bullet->style_p = style_ori; /*Revert the style*/
|
||||
#endif
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_bullet_design_f(bullet, mask, mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file lv_rect.c
|
||||
* @file lv_cont.c
|
||||
*
|
||||
*/
|
||||
|
||||
@ -465,10 +465,19 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
|
||||
h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
|
||||
}
|
||||
}
|
||||
/*If here is only one object in the row then align it to the middle*/
|
||||
/*If there is only one object in the row then align it to the middle*/
|
||||
else if (obj_num == 1) {
|
||||
lv_obj_align(child_rs, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);
|
||||
}
|
||||
/*If are two object in the row then align them proportionally*/
|
||||
else if (obj_num == 2) {
|
||||
lv_obj_t * obj1 = child_rs;
|
||||
lv_obj_t * obj2 = ll_get_prev(&cont->child_ll, child_rs);
|
||||
w_row = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);
|
||||
cord_t pad = (w_obj - w_row) / 3;
|
||||
lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad, act_y);
|
||||
lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad, act_y);
|
||||
}
|
||||
/* Align the children (from child_rs to child_rc)*/
|
||||
else {
|
||||
w_row -= style->opad * obj_num;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "lv_ddlist.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@ -70,6 +71,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->opened = 0;
|
||||
ext->auto_size = 0;
|
||||
ext->sel_opt = 0;
|
||||
ext->num_opt = 0;
|
||||
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
|
||||
ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);
|
||||
|
||||
@ -83,7 +85,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
if(copy == NULL) {
|
||||
lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
|
||||
lv_obj_set_drag(scrl, false);
|
||||
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
|
||||
lv_cont_set_fit(scrl, true, true);
|
||||
|
||||
ext->opt_label = lv_label_create(new_ddlist, NULL);
|
||||
lv_cont_set_fit(new_ddlist, true, false);
|
||||
@ -100,6 +103,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->sel_opt = copy_ext->sel_opt;
|
||||
ext->auto_size = copy_ext->auto_size;
|
||||
ext->cb = copy_ext->cb;
|
||||
ext->num_opt = copy_ext->num_opt;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refr_style(new_ddlist);
|
||||
@ -129,7 +133,44 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
if(ext->opened == false) {
|
||||
ext->opened = true;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
if(ext->opened != false) {
|
||||
ext->opened = false;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(ext->sel_opt +1 < ext->num_opt) {
|
||||
ext->sel_opt ++;
|
||||
lv_obj_inv(ddlist);
|
||||
if(ext->cb != NULL) {
|
||||
ext->cb(ddlist, NULL);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
if(ext->sel_opt > 0) {
|
||||
ext->sel_opt --;
|
||||
lv_obj_inv(ddlist);
|
||||
if(ext->cb != NULL) {
|
||||
ext->cb(ddlist, NULL);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ESC) {
|
||||
if(ext->opened != false) ext->opened = false;
|
||||
if(ext->opened == false) ext->opened = true;
|
||||
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
@ -158,6 +199,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
|
||||
i++;
|
||||
}
|
||||
|
||||
ext->num_opt = i;
|
||||
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
|
||||
@ -169,6 +212,15 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
|
||||
void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
|
||||
/*Count the '\n'-s to determine the number of options*/
|
||||
ext->num_opt = 0;
|
||||
uint16_t i;
|
||||
for(i = 0; options[i] != '\0'; i++) {
|
||||
if(options[i] == '\n') ext->num_opt++;
|
||||
}
|
||||
ext->num_opt++; /*Last option in the at row*/
|
||||
|
||||
lv_label_set_text(ext->opt_label, options);
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
@ -352,13 +404,12 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_m
|
||||
const font_t * font = style->font;
|
||||
cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS;
|
||||
area_t rect_area;
|
||||
lv_style_t * style_page_scrl = lv_obj_get_style(lv_page_get_scrl(ddlist));
|
||||
rect_area.y1 = ext->opt_label->cords.y1;
|
||||
rect_area.y1 += ext->sel_opt * (font_h + style->line_space);
|
||||
rect_area.y1 -= style->line_space / 2;
|
||||
|
||||
rect_area.y2 = rect_area.y1 + font_h + style->line_space;
|
||||
rect_area.x1 = ext->opt_label->cords.x1 - style_page_scrl->hpad;
|
||||
rect_area.x1 = ext->opt_label->cords.x1 - style->hpad;
|
||||
rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(ddlist));
|
||||
|
||||
lv_draw_rect(&rect_area, mask, ext->style_sel);
|
||||
@ -417,7 +468,7 @@ static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * disp
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the size of drop down list according its start (open or closed)
|
||||
* Refresh the size of drop down list according its status (open or closed)
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param anim_time animations time for open/close [ms]
|
||||
*/
|
||||
|
@ -43,7 +43,8 @@ typedef struct
|
||||
/*New data for this type */
|
||||
lv_obj_t * opt_label; /*Label for the options*/
|
||||
lv_style_t * style_sel; /*Style of the selected option*/
|
||||
lv_action_t cb; /*Pointer to function to call when an option is slected*/
|
||||
lv_action_t cb; /*Pointer to function to call when an option is selected*/
|
||||
uint16_t num_opt; /*Number of options*/
|
||||
uint16_t sel_opt; /*Index of the current option*/
|
||||
uint16_t anim_time; /*Open/Close animation time [ms]*/
|
||||
uint8_t opened :1; /*1: The list is opened*/
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "misc/math/math_base.h"
|
||||
#include "lv_label.h"
|
||||
#include "../lv_obj/lv_obj.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "misc/gfx/text.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
@ -83,6 +84,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->txt = NULL;
|
||||
ext->static_txt = 0;
|
||||
ext->recolor = 0;
|
||||
ext->no_break = 0;
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
||||
ext->offset.x = 0;
|
||||
@ -307,6 +309,19 @@ void lv_label_set_recolor(lv_obj_t * label, bool recolor)
|
||||
lv_label_refr_text(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the label the ignore (or accept) line breaks on '\n'
|
||||
* @param label pointer to a label object
|
||||
* @param en true: ignore line breaks, false: make line breaks on '\n'
|
||||
*/
|
||||
void lv_label_set_no_break(lv_obj_t * label, bool en)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
ext->no_break = en == false ? 0 : 1;
|
||||
|
||||
lv_label_refr_text(label);
|
||||
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@ -366,6 +381,7 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
|
||||
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
/*If the width will be expanded the set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
|
||||
@ -401,6 +417,8 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
|
||||
|
||||
}
|
||||
|
||||
if(x > style->letter_space) x-= style->letter_space;
|
||||
|
||||
if(style->txt_align == LV_TXT_ALIGN_MID) {
|
||||
cord_t line_w;
|
||||
line_w = txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
@ -434,6 +452,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
|
||||
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
|
||||
@ -468,11 +487,9 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
|
||||
}
|
||||
|
||||
x += (font_get_width(font, txt[i]) >> FONT_ANTIALIAS) + style->letter_space;
|
||||
|
||||
if(pos->x < x) break;
|
||||
}
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -496,25 +513,27 @@ static bool lv_label_design(lv_obj_t * label, const area_t * mask, lv_design_mod
|
||||
/* A label never covers an area */
|
||||
if(mode == LV_DESIGN_COVER_CHK) return false;
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/*TEST: draw a background for the label*/
|
||||
area_t cords;
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
lv_obj_get_cords(label, &cords);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
lv_group_t * g = lv_obj_get_group(label);
|
||||
if(lv_group_get_focused(g) == label) {
|
||||
lv_draw_rect(&cords, mask, style);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*TEST: draw a background for the label*/
|
||||
//lv_vfill(&label->cords, mask, COLOR_LIME, OPA_COVER);
|
||||
|
||||
area_t cords;
|
||||
lv_obj_get_cords(label, &cords);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
txt_flag_t flag = TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
if(strcmp("Folder1", ext->txt) == 0) {
|
||||
uint8_t i;
|
||||
i = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
lv_draw_label(&cords, mask, lv_obj_get_style(label), ext->txt, flag, &ext->offset);
|
||||
|
||||
|
||||
lv_draw_label(&cords, mask, style, ext->txt, flag, &ext->offset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -546,6 +565,7 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
txt_flag_t flag = TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
txt_get_size(&size, ext->txt, font, style->letter_space, style->line_space, max_w, flag);
|
||||
|
||||
/*Refresh the full size in expand mode*/
|
||||
|
@ -48,10 +48,11 @@ typedef struct
|
||||
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
|
||||
char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/
|
||||
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
||||
point_t offset;
|
||||
point_t offset; /*Text draw position offset*/
|
||||
uint8_t static_txt :1; /*Flag to indicate the text is static*/
|
||||
uint8_t recolor :1; /*Enable in-line letter re-coloring*/
|
||||
uint8_t expand :1; /*Force expand size when solving line length (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t expand :1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t no_break :1; /*Ignore new line characters*/
|
||||
}lv_label_ext_t;
|
||||
|
||||
/**********************
|
||||
@ -119,12 +120,13 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);
|
||||
*/
|
||||
void lv_label_set_recolor(lv_obj_t * label, bool recolor);
|
||||
|
||||
|
||||
/**
|
||||
* Enable the password mode
|
||||
* Set the label the ignore (or accept) line breaks on '\n'
|
||||
* @param label pointer to a label object
|
||||
* @param pwd true: enable password mode, false: disable
|
||||
* @param en true: ignore line breaks, false: make line breaks on '\n'
|
||||
*/
|
||||
void lv_label_set_pwd_mode(lv_obj_t * label, bool pwd);
|
||||
void lv_label_set_no_break(lv_obj_t * label, bool en);
|
||||
|
||||
/**
|
||||
* Get the text of a label
|
||||
|
@ -10,13 +10,18 @@
|
||||
#if USE_LV_LIST != 0
|
||||
|
||||
#include "lv_list.h"
|
||||
#include <lvgl/lv_objx/lv_cont.h>
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "lvgl/lv_objx/lv_cont.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "misc/math/math_base.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_LIST_LAYOUT_DEF LV_CONT_LAYOUT_COL_M
|
||||
#ifndef LV_LIST_FOCUS_TIME
|
||||
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -29,6 +34,8 @@
|
||||
static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_t mode);
|
||||
#endif
|
||||
|
||||
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@ -108,6 +115,85 @@ bool lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
/* Include the ancient signal function */
|
||||
valid = lv_page_signal(list, sign, param);
|
||||
|
||||
/* The object can be deleted so check its validity and then
|
||||
* make the object specific signal handling */
|
||||
if(valid != false) {
|
||||
if(sign == LV_SIGNAL_FOCUS) {
|
||||
/*Get the first button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
btn_prev = btn;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
|
||||
/*Get the last pressed button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn_prev = btn;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn_prev != NULL && btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
/*Get the last pressed button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_obj_t * btn_prev = lv_list_get_next_btn(list, btn);
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_action_t rel_action;
|
||||
rel_action = lv_btn_get_rel_action(btn);
|
||||
if(rel_action != NULL) rel_action(btn, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -175,19 +261,37 @@ void lv_list_up(lv_obj_t * list)
|
||||
{
|
||||
/*Search the first list element which 'y' coordinate is below the parent
|
||||
* and position the list to show this element on the bottom*/
|
||||
lv_obj_t * h = lv_obj_get_parent(list);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * e;
|
||||
lv_obj_t * e_prev = NULL;
|
||||
e = lv_obj_get_child(list, NULL);
|
||||
e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->cords.y2 <= h->cords.y2) {
|
||||
if(e_prev != NULL)
|
||||
lv_obj_set_y(list, lv_obj_get_height(h) -
|
||||
(lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev)));
|
||||
if(e->cords.y2 <= list->cords.y2) {
|
||||
if(e_prev != NULL) {
|
||||
cord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
|
||||
#if LV_LIST_FOCUS_TIME == 0
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
#else
|
||||
anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (anim_fp_t)lv_obj_set_y;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_FOCUS_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
anim_create(&a);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
e_prev = e;
|
||||
e = lv_obj_get_child(list, e);
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,19 +303,36 @@ void lv_list_down(lv_obj_t * list)
|
||||
{
|
||||
/*Search the first list element which 'y' coordinate is above the parent
|
||||
* and position the list to show this element on the top*/
|
||||
lv_obj_t * h = lv_obj_get_parent(list);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * e;
|
||||
e = lv_obj_get_child(list, NULL);
|
||||
e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->cords.y1 < h->cords.y1) {
|
||||
lv_obj_set_y(list, -lv_obj_get_y(e));
|
||||
if(e->cords.y1 < list->cords.y1) {
|
||||
cord_t new_y = -lv_obj_get_y(e);
|
||||
#if LV_LIST_FOCUS_TIME == 0
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
#else
|
||||
anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (anim_fp_t)lv_obj_set_y;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_FOCUS_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
anim_create(&a);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
e = lv_obj_get_child(list, e);
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@ -236,8 +357,9 @@ void lv_list_set_sb_out(lv_obj_t * list, bool out)
|
||||
*/
|
||||
void lv_list_set_element_text_roll(lv_obj_t * liste, bool en)
|
||||
{
|
||||
/*The last child is the label*/
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
lv_obj_t * label = lv_list_get_element_label(liste);
|
||||
if(label == NULL) return;
|
||||
|
||||
if(en == false) {
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_DOTS);
|
||||
} else {
|
||||
@ -269,12 +391,11 @@ void lv_list_set_styles_btn(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr,
|
||||
ext->styles_btn[LV_BTN_STATE_TPR] = tpr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = ina;
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
|
||||
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
|
||||
while(liste != NULL)
|
||||
{
|
||||
lv_btn_set_styles(liste, rel, pr, trel, tpr, ina);
|
||||
liste = lv_obj_get_child(scrl, liste);
|
||||
liste = lv_list_get_next_btn(list, liste);
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,16 +411,14 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
|
||||
|
||||
ext->style_img = style;
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
|
||||
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
|
||||
lv_obj_t * img;
|
||||
while(liste != NULL)
|
||||
{
|
||||
img = lv_obj_get_child(liste, NULL); /*Now img = the label*/
|
||||
img = lv_obj_get_child(liste, img); /*Now img = the image (if ULL then no image) */
|
||||
img = lv_list_get_element_img(liste);
|
||||
if(img != NULL) lv_obj_set_style(img, style);
|
||||
|
||||
liste = lv_obj_get_child(scrl, liste);
|
||||
liste = lv_list_get_next_btn(list, liste);
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,11 +433,47 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
|
||||
*/
|
||||
const char * lv_list_get_element_text(lv_obj_t * liste)
|
||||
{
|
||||
/*The last child is the label*/
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
lv_obj_t * label = lv_list_get_element_label(liste);
|
||||
if(label == NULL) return "";
|
||||
return lv_label_get_text(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the label from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste)
|
||||
{
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
if(label == NULL) return NULL;
|
||||
|
||||
while(label->signal_f != lv_label_signal) {
|
||||
label = lv_obj_get_child(liste, NULL);
|
||||
if(label == NULL) break;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the image from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste)
|
||||
{
|
||||
lv_obj_t * img = lv_obj_get_child(liste, NULL);
|
||||
if(img == NULL) return NULL;
|
||||
|
||||
while(img->signal_f != lv_img_signal) {
|
||||
img = lv_obj_get_child(liste, NULL);
|
||||
if(img == NULL) break;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scroll bar outside attribute
|
||||
* @param list pointer to list object
|
||||
@ -388,4 +543,29 @@ static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the next button from list
|
||||
* @param list pointer to a list object
|
||||
* @param prev_btn pointer to button. Search the next after it.
|
||||
* @return pointer to the next button or NULL
|
||||
*/
|
||||
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
{
|
||||
/* Not a good practice but user can add/create objects to the lists manually.
|
||||
* When getting the next button try to be sure that it is at least a button */
|
||||
|
||||
lv_obj_t * btn ;
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
if(btn == NULL) return NULL;
|
||||
|
||||
while(btn->signal_f != lv_btn_signal) {
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
if(btn == NULL) break;
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -141,6 +141,20 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style);
|
||||
*/
|
||||
const char * lv_list_get_element_text(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the label from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the image from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the scroll bar outside attribute
|
||||
* @param list pointer to list object
|
||||
|
@ -11,6 +11,7 @@
|
||||
#if USE_LV_MBOX != 0
|
||||
|
||||
#include "lv_mbox.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "misc/math/math_base.h"
|
||||
|
||||
@ -132,13 +133,11 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
|
||||
area_get_height(param) != lv_obj_get_height(mbox)) {
|
||||
lv_mbox_realign(mbox);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS) {
|
||||
} else if(sign == LV_SIGNAL_LONG_PRESS) {
|
||||
lv_mbox_start_auto_close(mbox, 0);
|
||||
lv_dispi_wait_release(param);
|
||||
valid = false;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
/*Refresh all the buttons*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn;
|
||||
@ -150,6 +149,90 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
/*Get the first button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
btn_prev = btn;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
/*Get the 'pressed' button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_mbox_ext_t * ext = lv_obj_get_ext(mbox);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
/*Get the last pressed button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn_prev = btn;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn_prev != NULL && btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
/*Get the last pressed button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn);
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
/*Get the 'pressed' button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_action_t rel_action;
|
||||
rel_action = lv_btn_get_rel_action(btn);
|
||||
if(rel_action != NULL) rel_action(btn, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#if USE_LV_PAGE != 0
|
||||
|
||||
#include "misc/math/math_base.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_objx/lv_page.h"
|
||||
#include "../lv_objx/lv_cont.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
@ -28,13 +29,15 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_page_sb_refresh(lv_obj_t * main);
|
||||
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_f_t ancestor_design_f;
|
||||
static lv_design_f_t ancestor_page_design_f;
|
||||
static lv_design_f_t ancestor_scrl_design_f;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@ -72,18 +75,20 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->sb_width = LV_DPI / 8; /*Will be modified later*/
|
||||
ext->sb_mode = LV_PAGE_SB_MODE_ON;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_page);
|
||||
if(ancestor_page_design_f == NULL) ancestor_page_design_f = lv_obj_get_design_f(new_page);
|
||||
|
||||
/*Init the new page object*/
|
||||
if(copy == NULL) {
|
||||
lv_style_t * style = lv_style_get(LV_STYLE_PRETTY_COLOR, NULL);
|
||||
ext->scrl = lv_cont_create(new_page, NULL);
|
||||
if(ancestor_scrl_design_f == NULL) ancestor_scrl_design_f = lv_obj_get_design_f(ext->scrl);
|
||||
lv_obj_set_signal_f(ext->scrl, lv_scrl_signal);
|
||||
lv_obj_set_drag(ext->scrl, true);
|
||||
lv_obj_set_drag_throw(ext->scrl, true);
|
||||
lv_obj_set_protect(ext->scrl, LV_PROTECT_PARENT);
|
||||
lv_cont_set_fit(ext->scrl, true, true);
|
||||
lv_cont_set_fit(ext->scrl, false, true);
|
||||
lv_obj_set_style(ext->scrl, lv_style_get(LV_STYLE_PRETTY, NULL));
|
||||
lv_obj_set_design_f(ext->scrl, lv_scrl_design);
|
||||
|
||||
lv_page_set_sb_width(new_page, style->hpad);
|
||||
lv_page_set_sb_mode(new_page, ext->sb_mode);
|
||||
@ -138,60 +143,60 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
if(obj_valid != false) {
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(page);
|
||||
lv_obj_t * child;
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CHILD_CHG: /*Move children to the scrollable object*/
|
||||
child = lv_obj_get_child(page, NULL);
|
||||
while(child != NULL) {
|
||||
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
|
||||
lv_obj_t * tmp = child;
|
||||
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
||||
lv_obj_set_parent(tmp, ext->scrl);
|
||||
} else {
|
||||
child = lv_obj_get_child(page, child);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_STYLE_CHG:
|
||||
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
|
||||
ext->sbh_draw = 1;
|
||||
ext->sbv_draw = 1;
|
||||
} else {
|
||||
ext->sbh_draw = 0;
|
||||
ext->sbv_draw = 0;
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
/*Refresh the scrollbar and notify the scrl if the size is changed*/
|
||||
if(ext->scrl != NULL &&
|
||||
(lv_obj_get_width(page) != area_get_width(param) ||
|
||||
lv_obj_get_height(page) != area_get_height(param))) {
|
||||
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
|
||||
|
||||
/*The scrolbars are important olny if they are visible now*/
|
||||
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
|
||||
lv_page_sb_refresh(page);
|
||||
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_PRESSED:
|
||||
if(ext->pr_action != NULL) {
|
||||
ext->pr_action(page, param);
|
||||
if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the scrollable object*/
|
||||
child = lv_obj_get_child(page, NULL);
|
||||
while(child != NULL) {
|
||||
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
|
||||
lv_obj_t * tmp = child;
|
||||
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
||||
lv_obj_set_parent(tmp, ext->scrl);
|
||||
} else {
|
||||
child = lv_obj_get_child(page, child);
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_RELEASED:
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(ext->rel_action != NULL) {
|
||||
ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_style_t * style = lv_obj_get_style(page);
|
||||
if(lv_cont_get_hfit(ext->scrl) == false) {
|
||||
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
|
||||
}
|
||||
|
||||
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
|
||||
ext->sbh_draw = 1;
|
||||
ext->sbv_draw = 1;
|
||||
} else {
|
||||
ext->sbh_draw = 0;
|
||||
ext->sbv_draw = 0;
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
lv_style_t * style = lv_obj_get_style(page);
|
||||
/*Refresh the scrollbar and notify the scrl if the size is changed*/
|
||||
if(ext->scrl != NULL &&
|
||||
(lv_obj_get_width(page) != area_get_width(param) ||
|
||||
lv_obj_get_height(page) != area_get_height(param))) {
|
||||
|
||||
if(lv_cont_get_hfit(ext->scrl) == false) {
|
||||
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
|
||||
|
||||
/*The scrollbars are important olny if they are visible now*/
|
||||
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
|
||||
lv_page_sb_refresh(page);
|
||||
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_PRESSED) {
|
||||
if(ext->pr_action != NULL) {
|
||||
ext->pr_action(page, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(ext->rel_action != NULL) {
|
||||
ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,118 +220,112 @@ static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param)
|
||||
* make the object specific signal handling */
|
||||
if(obj_valid != false) {
|
||||
|
||||
cord_t new_x;
|
||||
cord_t new_y;
|
||||
bool refr_x = false;
|
||||
bool refr_y = false;
|
||||
area_t page_cords;
|
||||
area_t obj_cords;
|
||||
lv_obj_t * page = lv_obj_get_parent(scrl);
|
||||
lv_style_t * page_style = lv_obj_get_style(page);
|
||||
lv_page_ext_t * page_ext = lv_obj_get_ext(page);
|
||||
cord_t hpad = page_style->hpad;
|
||||
cord_t vpad = page_style->vpad;
|
||||
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
new_x = lv_obj_get_x(scrl);
|
||||
new_y = lv_obj_get_y(scrl);
|
||||
lv_obj_get_cords(scrl, &obj_cords);
|
||||
lv_obj_get_cords(page, &page_cords);
|
||||
if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
cord_t new_x;
|
||||
cord_t new_y;
|
||||
bool refr_x = false;
|
||||
bool refr_y = false;
|
||||
area_t page_cords;
|
||||
area_t scrl_cords;
|
||||
cord_t hpad = page_style->hpad;
|
||||
cord_t vpad = page_style->vpad;
|
||||
|
||||
/*scrollable width smaller then page width? -> align to left*/
|
||||
if(area_get_width(&obj_cords) + 2 * hpad < area_get_width(&page_cords)) {
|
||||
if(obj_cords.x1 != page_cords.x1 + hpad) {
|
||||
new_x = hpad;
|
||||
refr_x = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus hpad) */
|
||||
if(obj_cords.x2 < page_cords.x2 - hpad) {
|
||||
new_x = area_get_width(&page_cords) - area_get_width(&obj_cords) - hpad; /* Right align */
|
||||
refr_x = true;
|
||||
}
|
||||
if (obj_cords.x1 > page_cords.x1 + hpad) {
|
||||
new_x = hpad; /*Left align*/
|
||||
refr_x = true;
|
||||
}
|
||||
new_x = lv_obj_get_x(scrl);
|
||||
new_y = lv_obj_get_y(scrl);
|
||||
lv_obj_get_cords(scrl, &scrl_cords);
|
||||
lv_obj_get_cords(page, &page_cords);
|
||||
|
||||
/*scrollable width smaller then page width? -> align to left*/
|
||||
if(area_get_width(&scrl_cords) + 2 * hpad < area_get_width(&page_cords)) {
|
||||
if(scrl_cords.x1 != page_cords.x1 + hpad) {
|
||||
new_x = hpad;
|
||||
refr_x = true;
|
||||
}
|
||||
|
||||
/*scrollable height smaller then page height? -> align to left*/
|
||||
if(area_get_height(&obj_cords) + 2 * vpad < area_get_height(&page_cords)) {
|
||||
if(obj_cords.y1 != page_cords.y1 + vpad) {
|
||||
new_y = vpad;
|
||||
refr_y = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus vpad) */
|
||||
if(obj_cords.y2 < page_cords.y2 - vpad) {
|
||||
new_y = area_get_height(&page_cords) - area_get_height(&obj_cords) - vpad; /* Bottom align */
|
||||
refr_y = true;
|
||||
}
|
||||
if (obj_cords.y1 > page_cords.y1 + vpad) {
|
||||
new_y = vpad; /*Top align*/
|
||||
refr_y = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus hpad) */
|
||||
if(scrl_cords.x2 < page_cords.x2 - hpad) {
|
||||
new_x = area_get_width(&page_cords) - area_get_width(&scrl_cords) - hpad; /* Right align */
|
||||
refr_x = true;
|
||||
}
|
||||
if(refr_x != false || refr_y != false) {
|
||||
lv_obj_set_pos(scrl, new_x, new_y);
|
||||
if (scrl_cords.x1 > page_cords.x1 + hpad) {
|
||||
new_x = hpad; /*Left align*/
|
||||
refr_x = true;
|
||||
}
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_DRAG_BEGIN:
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
|
||||
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
|
||||
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
|
||||
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
|
||||
page_ext->sbv_draw = 1;
|
||||
}
|
||||
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
|
||||
page_ext->sbh_draw = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_DRAG_END:
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
|
||||
area_t sb_area_tmp;
|
||||
if(page_ext->sbh_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbh);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbh_draw = 0;
|
||||
}
|
||||
if(page_ext->sbv_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbv);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbv_draw = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_PRESSED:
|
||||
if(page_ext->pr_action != NULL) {
|
||||
page_ext->pr_action(page, param);
|
||||
/*scrollable height smaller then page height? -> align to left*/
|
||||
if(area_get_height(&scrl_cords) + 2 * vpad < area_get_height(&page_cords)) {
|
||||
if(scrl_cords.y1 != page_cords.y1 + vpad) {
|
||||
new_y = vpad;
|
||||
refr_y = true;
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_RELEASED:
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(page_ext->rel_action != NULL) {
|
||||
page_ext->rel_action(page, param);
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus vpad) */
|
||||
if(scrl_cords.y2 < page_cords.y2 - vpad) {
|
||||
new_y = area_get_height(&page_cords) - area_get_height(&scrl_cords) - vpad; /* Bottom align */
|
||||
refr_y = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (scrl_cords.y1 > page_cords.y1 + vpad) {
|
||||
new_y = vpad; /*Top align*/
|
||||
refr_y = true;
|
||||
}
|
||||
}
|
||||
if(refr_x != false || refr_y != false) {
|
||||
lv_obj_set_pos(scrl, new_x, new_y);
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
if(lv_cont_get_hfit(scrl) == false) {
|
||||
lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->hpad);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DRAG_BEGIN) {
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
|
||||
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
|
||||
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
|
||||
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
|
||||
page_ext->sbv_draw = 1;
|
||||
}
|
||||
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
|
||||
page_ext->sbh_draw = 1;
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DRAG_END) {
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
|
||||
area_t sb_area_tmp;
|
||||
if(page_ext->sbh_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbh);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbh_draw = 0;
|
||||
}
|
||||
if(page_ext->sbv_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbv);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbv_draw = 0;
|
||||
}
|
||||
}
|
||||
}else if(sign == LV_SIGNAL_PRESSED) {
|
||||
if(page_ext->pr_action != NULL) {
|
||||
page_ext->pr_action(page, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(page_ext->rel_action != NULL) {
|
||||
page_ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,41 +533,85 @@ lv_style_t * lv_page_get_style_sb(lv_obj_t * page)
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode)
|
||||
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_design_f(page, mask, mode);
|
||||
return ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
ancestor_design_f(page, mask, mode);
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/
|
||||
ancestor_design_f(page, mask, mode);
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(page);
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(scrl);
|
||||
|
||||
/*Draw the scrollbars*/
|
||||
area_t sb_area;
|
||||
if(ext->sbh_draw != 0) {
|
||||
/*Convert the relative coordinates to absolute*/
|
||||
area_cpy(&sb_area, &ext->sbh);
|
||||
sb_area.x1 += page->cords.x1;
|
||||
sb_area.y1 += page->cords.y1;
|
||||
sb_area.x2 += page->cords.x1;
|
||||
sb_area.y2 += page->cords.y1;
|
||||
sb_area.x1 += scrl->cords.x1;
|
||||
sb_area.y1 += scrl->cords.y1;
|
||||
sb_area.x2 += scrl->cords.x1;
|
||||
sb_area.y2 += scrl->cords.y1;
|
||||
lv_draw_rect(&sb_area, mask, ext->style_sb);
|
||||
}
|
||||
|
||||
if(ext->sbv_draw != 0) {
|
||||
/*Convert the relative coordinates to absolute*/
|
||||
area_cpy(&sb_area, &ext->sbv);
|
||||
sb_area.x1 += page->cords.x1;
|
||||
sb_area.y1 += page->cords.y1;
|
||||
sb_area.x2 += page->cords.x1;
|
||||
sb_area.y2 += page->cords.y1;
|
||||
sb_area.x1 += scrl->cords.x1;
|
||||
sb_area.y1 += scrl->cords.y1;
|
||||
sb_area.x2 += scrl->cords.x1;
|
||||
sb_area.y2 += scrl->cords.y1;
|
||||
lv_draw_rect(&sb_area, mask, ext->style_sb);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Handle the drawing related tasks of the scrollable object
|
||||
* @param scrl pointer to an object
|
||||
* @param mask the object will be drawn only in this area
|
||||
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
|
||||
* (return 'true' if yes)
|
||||
* LV_DESIGN_DRAW: draw the object (always return 'true')
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/* If the page is the active in a group and
|
||||
* the background (page) is not visible (transparent or empty)
|
||||
* then activate the style of the scrollable*/
|
||||
lv_style_t * style_ori = lv_obj_get_style(scrl);
|
||||
lv_obj_t * page = lv_obj_get_parent(scrl);
|
||||
lv_style_t * style_page = lv_obj_get_style(page);
|
||||
lv_group_t * g = lv_obj_get_group(page);
|
||||
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
|
||||
if(lv_group_get_focused(g) == page) {
|
||||
lv_style_t * style_mod;
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
scrl->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
scrl->style_p = style_ori; /*Revert the style*/
|
||||
#endif
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the position and size of the scroll bars.
|
||||
|
@ -10,12 +10,14 @@
|
||||
#if USE_LV_SLIDER != 0
|
||||
|
||||
#include "lv_slider.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/math/math_base.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_SLIDER_SIZE_MIN (2 * LV_DOWNSCALE) /*hpad and vpad cannot make the bar or indicator smaller then this [px]*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -52,7 +54,6 @@ static lv_design_f_t ancestor_design_f;
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
{
|
||||
/*Create the ancestor slider*/
|
||||
/*TODO modify it to the ancestor create function */
|
||||
lv_obj_t * new_slider = lv_bar_create(par, copy);
|
||||
dm_assert(new_slider);
|
||||
|
||||
@ -102,7 +103,6 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
|
||||
bool valid;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
/* TODO update it to the ancestor's signal function*/
|
||||
valid = lv_bar_signal(slider, sign, param);
|
||||
|
||||
/* The object can be deleted so check its validity and then
|
||||
@ -145,10 +145,19 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
|
||||
lv_obj_get_height(slider) != area_get_height(param)) {
|
||||
slider->signal_f(slider, LV_SIGNAL_REFR_EXT_SIZE, NULL);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
cord_t x = MATH_MIN(w, h);
|
||||
if(slider->ext_size < x) slider->ext_size = x;
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_slider_ext_t * ext = lv_obj_get_ext(slider);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
lv_bar_set_value(slider, lv_bar_get_value(slider) + 1);
|
||||
if(ext->cb != NULL) ext->cb(slider, NULL);
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
lv_bar_set_value(slider, lv_bar_get_value(slider) - 1);
|
||||
if(ext->cb != NULL) ext->cb(slider, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,24 +247,47 @@ static bool lv_slider_design(lv_obj_t * slider, const area_t * mask, lv_design_m
|
||||
lv_style_t * style_knob = lv_slider_get_style_knob(slider);
|
||||
lv_style_t * style_indic = lv_bar_get_style_indic(slider);
|
||||
|
||||
/*Draw the bar*/
|
||||
area_t area_bar;
|
||||
|
||||
area_cpy(&area_bar, &slider->cords);
|
||||
area_bar.x1 += style_knob->hpad;
|
||||
area_bar.x2 -= style_knob->hpad;
|
||||
area_bar.y1 += style_knob->vpad;
|
||||
area_bar.y2 -= style_knob->vpad;
|
||||
/*Be sure at least vpad/hpad width bar will remain*/
|
||||
cord_t vpad_bar = style_indic->vpad;
|
||||
cord_t hpad_bar = style_indic->hpad;
|
||||
if(vpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
|
||||
vpad_bar = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
if(hpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
|
||||
hpad_bar = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
|
||||
area_bar.x1 += hpad_bar;
|
||||
area_bar.x2 -= hpad_bar;
|
||||
area_bar.y1 += vpad_bar;
|
||||
area_bar.y2 -= vpad_bar;
|
||||
lv_draw_rect(&area_bar, mask, style_slider);
|
||||
|
||||
/*Draw the indicator*/
|
||||
area_t area_indic;
|
||||
area_cpy(&area_indic, &area_bar);
|
||||
area_indic.x1 += style_indic->hpad;
|
||||
area_indic.x2 -= style_indic->hpad;
|
||||
area_indic.y1 += style_indic->vpad;
|
||||
area_indic.y2 -= style_indic->vpad;
|
||||
|
||||
/*Be sure at least vpad/hpad width indicator will remain*/
|
||||
cord_t vpad_indic = style_indic->vpad;
|
||||
cord_t hpad_indic = style_indic->hpad;
|
||||
if(vpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
|
||||
vpad_indic = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
if(hpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
|
||||
hpad_indic = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
|
||||
area_indic.x1 += hpad_indic;
|
||||
area_indic.x2 -= hpad_indic;
|
||||
area_indic.y1 += vpad_indic;
|
||||
area_indic.y2 -= vpad_indic;
|
||||
|
||||
cord_t slider_w = area_get_width(&slider->cords);
|
||||
cord_t slider_h = area_get_height(&slider->cords);
|
||||
|
||||
cord_t act_value = lv_bar_get_value(slider);
|
||||
cord_t min_value = lv_bar_get_min_value(slider);
|
||||
cord_t max_value = lv_bar_get_max_value(slider);
|
||||
|
110
lv_objx/lv_ta.c
110
lv_objx/lv_ta.c
@ -11,6 +11,7 @@
|
||||
#if USE_LV_TA != 0
|
||||
|
||||
#include "lv_ta.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
@ -114,6 +115,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
lv_ta_ext_t * copy_ext = lv_obj_get_ext(copy);
|
||||
ext->label = lv_label_create(new_ta, copy_ext->label);
|
||||
ext->cursor_show = copy_ext->cursor_show;
|
||||
ext->pwd_mode = copy_ext->pwd_mode;
|
||||
lv_page_glue_obj(ext->label, true);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
@ -158,32 +160,39 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
|
||||
if(valid != false) {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style = lv_obj_get_style(ta);
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CLEANUP:
|
||||
/* Nothing to clean up.
|
||||
* (The created label will be deleted automatically) */
|
||||
break;
|
||||
case LV_SIGNAL_STYLE_CHG:
|
||||
if(ext->label) {
|
||||
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
break;
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(ext->pwd_tmp != NULL) dm_free(ext->pwd_tmp);
|
||||
|
||||
/* (The created label will be deleted automatically) */
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
if(ext->label) {
|
||||
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
/*Set the label width according to the text area width*/
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
if(ext->label != NULL) {
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
if(ext->label != NULL) {
|
||||
if(lv_obj_get_width(ta) != area_get_width(param) ||
|
||||
lv_obj_get_height(ta) != area_get_height(param)) {
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 * style->hpad);
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT) {
|
||||
lv_ta_cursor_right(ta);
|
||||
} else if(c == LV_GROUP_KEY_LEFT) {
|
||||
lv_ta_cursor_left(ta);
|
||||
} else if(c == LV_GROUP_KEY_UP) {
|
||||
lv_ta_cursor_up(ta);
|
||||
} else if(c == LV_GROUP_KEY_DOWN) {
|
||||
lv_ta_cursor_down(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -305,6 +314,12 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
|
||||
lv_label_set_text(ext->label, txt);
|
||||
lv_ta_set_cursor_pos(ta, LV_TA_CUR_LAST);
|
||||
|
||||
/*Don't let 'width == 0' because cursor will not be visible*/
|
||||
if(lv_obj_get_width(ext->label) == 0) {
|
||||
lv_style_t * style = lv_obj_get_style(ext->label);
|
||||
lv_obj_set_width(ext->label, style->line_width);
|
||||
}
|
||||
|
||||
/*It is a valid x step so save it*/
|
||||
lv_ta_save_valid_cursor_x(ta);
|
||||
|
||||
@ -346,6 +361,11 @@ void lv_ta_del(lv_obj_t * ta)
|
||||
|
||||
/*Refresh the label*/
|
||||
lv_label_set_text(ext->label, buf);
|
||||
/*Don't let 'width == 0' because cursor will not be visible*/
|
||||
if(lv_obj_get_width(ext->label) == 0) {
|
||||
lv_style_t * style = lv_obj_get_style(ext->label);
|
||||
lv_obj_set_width(ext->label, style->line_width);
|
||||
}
|
||||
|
||||
/*Move the cursor to the place of the deleted character*/
|
||||
lv_ta_set_cursor_pos(ta, lv_ta_get_cursor_pos(ta) - 1);
|
||||
@ -397,6 +417,16 @@ void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)
|
||||
lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) +
|
||||
font_h + 2 * style_scrl->vpad));
|
||||
}
|
||||
/*Check the left (use the font_h as general unit)*/
|
||||
if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {
|
||||
lv_obj_set_x(label_par, - cur_pos.x + font_h);
|
||||
}
|
||||
|
||||
/*Check the right (use the font_h as general unit)*/
|
||||
if(label_cords.x1 + cur_pos.x + font_h + style_scrl->hpad > ta_cords.x2) {
|
||||
lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) +
|
||||
font_h + 2 * style_scrl->hpad));
|
||||
}
|
||||
|
||||
lv_obj_inv(ta);
|
||||
}
|
||||
@ -526,6 +556,36 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
|
||||
|
||||
ext->pwd_mode = en == false ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the text area to one line or back to normal
|
||||
* @param ta pointer to a Text area object
|
||||
* @param en true: one line, false: normal
|
||||
*/
|
||||
void lv_ta_set_one_line(lv_obj_t * ta, bool en)
|
||||
{
|
||||
if(en != false) {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style_ta = lv_obj_get_style(ta);
|
||||
lv_style_t * style_label = lv_obj_get_style(ext->label);
|
||||
|
||||
lv_cont_set_fit(lv_page_get_scrl(ta), true, true);
|
||||
lv_obj_set_height(ta, font_get_height(style_label->font) + style_ta->vpad * 2);
|
||||
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND);
|
||||
lv_label_set_no_break(ext->label, true);
|
||||
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
|
||||
} else {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style_ta = lv_obj_get_style(ta);
|
||||
|
||||
lv_cont_set_fit(lv_page_get_scrl(ta), false, true);
|
||||
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_no_break(ext->label, false);
|
||||
lv_obj_set_height(ta, LV_TA_DEF_HEIGHT);
|
||||
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@ -657,9 +717,9 @@ static bool lv_ta_scrling_design(lv_obj_t * scrling, const area_t * mask, lv_des
|
||||
|
||||
area_t cur_area;
|
||||
lv_style_t * labels_p = lv_obj_get_style(ta_ext->label);
|
||||
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1;
|
||||
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - scrl_style->line_width / 2 ;
|
||||
cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1;
|
||||
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width ;
|
||||
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width / 2 + (scrl_style->line_width & 0x1);
|
||||
cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + (font_get_height(labels_p->font) >> FONT_ANTIALIAS);
|
||||
|
||||
lv_style_t cur_rects;
|
||||
|
@ -147,6 +147,13 @@ void lv_ta_set_cursor_show(lv_obj_t * ta, bool show);
|
||||
*/
|
||||
void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en);
|
||||
|
||||
/**
|
||||
* Configure the Text area to one line or back to normal
|
||||
* @param ta pointer to a text area object
|
||||
* @param en true: one line, false: normal
|
||||
*/
|
||||
void lv_ta_set_one_line(lv_obj_t * ta, bool en);
|
||||
|
||||
/**
|
||||
* Get the text of the i the text area
|
||||
* @param ta obj pointer to a text area object
|
||||
|
Loading…
x
Reference in New Issue
Block a user