merge dev-v8
This commit is contained in:
169
src/lv_api_map.h
169
src/lv_api_map.h
@@ -27,173 +27,10 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*---------------------
|
||||
* V6.0 COMPATIBILITY
|
||||
*--------------------*/
|
||||
#if LV_USE_API_EXTENSION_V6
|
||||
|
||||
static inline void lv_task_once(lv_task_t * task)
|
||||
{
|
||||
lv_task_set_repeat_count(task, 1);
|
||||
}
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
|
||||
#define lv_checkbox_set_static_text lv_checkbox_set_text_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
|
||||
#define lv_chart_get_point_cnt lv_chart_get_point_count
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_DROPDOWN
|
||||
|
||||
static inline void lv_dropdown_set_draw_arrow(lv_obj_t * ddlist, bool en)
|
||||
{
|
||||
if(en) lv_dropdown_set_symbol(ddlist, LV_SYMBOL_DOWN);
|
||||
else lv_dropdown_set_symbol(ddlist, NULL);
|
||||
}
|
||||
|
||||
static inline bool lv_dropdown_get_draw_arrow(lv_obj_t * ddlist)
|
||||
{
|
||||
if(lv_dropdown_get_symbol(ddlist)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
#define lv_dropdown_set_static_options lv_dropdown_set_options_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_BAR
|
||||
|
||||
/**
|
||||
* Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum
|
||||
* position.
|
||||
* @param bar pointer to a bar object
|
||||
* @param en true: enable disable symmetric behavior; false: disable
|
||||
* @deprecated As of v7.0, you should use `lv_bar_set_type` instead.
|
||||
*/
|
||||
static inline void lv_bar_set_sym(lv_obj_t * bar, bool en)
|
||||
{
|
||||
if(en)
|
||||
lv_bar_set_type(bar, LV_BAR_TYPE_SYMMETRICAL);
|
||||
else
|
||||
lv_bar_set_type(bar, LV_BAR_TYPE_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the bar is symmetric or not.
|
||||
* @param bar pointer to a bar object
|
||||
* @return true: symmetric is enabled; false: disable
|
||||
* @deprecated As of v7.0, you should use `lv_bar_get_type` instead.
|
||||
*/
|
||||
static inline bool lv_bar_get_sym(lv_obj_t * bar)
|
||||
{
|
||||
return lv_bar_get_type(bar) == LV_BAR_TYPE_SYMMETRICAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL
|
||||
|
||||
#define lv_label_set_static_text lv_label_set_text_static
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
|
||||
/**
|
||||
* Make the slider symmetric to zero. The indicator will grow from zero instead of the minimum
|
||||
* position.
|
||||
* @param slider pointer to a bar object
|
||||
* @param en true: enable disable symmetric behavior; false: disable
|
||||
* @deprecated As of v7.0, you should use `lv_slider_set_type` instead.
|
||||
*/
|
||||
static inline void lv_slider_set_sym(lv_obj_t * slider, bool en)
|
||||
{
|
||||
lv_bar_set_sym(slider, en);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the slider is symmetric or not.
|
||||
* @param slider pointer to a slider object
|
||||
* @return true: symmetric is enabled; false: disable
|
||||
* @deprecated As of v7.0, you should use `lv_slider_get_type` instead.
|
||||
*/
|
||||
static inline bool lv_slider_get_sym(lv_obj_t * slider)
|
||||
{
|
||||
return lv_bar_get_sym(slider);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
|
||||
/**
|
||||
* Set a fixed width for the roller.
|
||||
* @param roller pointer to a roller object
|
||||
* @param w width
|
||||
* @deprecated As of v7.0, you should use `lv_roller_set_auto_fit` and set the width normally instead.
|
||||
*/
|
||||
static inline void lv_roller_set_fix_width(lv_obj_t * roller, lv_coord_t w)
|
||||
{
|
||||
lv_roller_set_auto_fit(roller, false);
|
||||
lv_obj_set_width(roller, w);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_PAGE
|
||||
#define lv_scrlbar_mode_t lv_scrollbar_mode_t
|
||||
|
||||
#define LV_SCRLBAR_MODE_OFF LV_SCROLLBAR_MODE_OFF
|
||||
#define LV_SCRLBAR_MODE_ON LV_SCROLLBAR_MODE_ON
|
||||
#define LV_SCRLBAR_MODE_DRAG LV_SCROLLBAR_MODE_DRAG
|
||||
#define LV_SCRLBAR_MODE_AUTO LV_SCROLLBAR_MODE_AUTO
|
||||
#define LV_SCRLBAR_MODE_HIDE LV_SCROLLBAR_MODE_HIDE
|
||||
#define LV_SCRLBAR_MODE_UNHIDE LV_SCROLLBAR_MODE_UNHIDE
|
||||
|
||||
|
||||
static inline void lv_page_set_scrlbar_mode(lv_obj_t * page, lv_scrlbar_mode_t sb_mode)
|
||||
{
|
||||
lv_page_set_scrollbar_mode(page, sb_mode);
|
||||
}
|
||||
static inline lv_scrollbar_mode_t lv_page_get_scrlbar_mode(lv_obj_t * page)
|
||||
{
|
||||
return lv_page_get_scrollbar_mode(page);
|
||||
}
|
||||
|
||||
|
||||
static inline lv_obj_t * lv_page_get_scrl(lv_obj_t * page)
|
||||
{
|
||||
return lv_page_get_scrollable(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_USE_API_EXTENSION_V6*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------
|
||||
* V7.0 COMPATIBILITY
|
||||
*--------------------*/
|
||||
#if LV_USE_API_EXTENSION_V7
|
||||
#if LV_USE_WIN
|
||||
|
||||
static inline lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
|
||||
{
|
||||
return lv_win_add_btn_right(win, img_src);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
static inline void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
|
||||
@@ -212,17 +49,17 @@ static inline void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * se
|
||||
static inline void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs,
|
||||
lv_coord_t y_ofs)
|
||||
{
|
||||
lv_obj_align_mid(obj, base, align, x_ofs, y_ofs);
|
||||
// lv_obj_align_mid(obj, base, align, x_ofs, y_ofs);
|
||||
}
|
||||
|
||||
static inline void lv_obj_align_origo_x(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs)
|
||||
{
|
||||
lv_obj_align_mid_y(obj, base, align, x_ofs);
|
||||
// lv_obj_align_mid_y(obj, base, align, x_ofs);
|
||||
}
|
||||
|
||||
static inline void lv_obj_align_origo_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t y_ofs)
|
||||
{
|
||||
lv_obj_align_mid_y(obj, base, align, y_ofs);
|
||||
// lv_obj_align_mid_y(obj, base, align, y_ofs);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_API_EXTENSION_V6*/
|
||||
|
||||
@@ -1490,24 +1490,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#ifndef LV_USE_CALENDAR
|
||||
# ifdef CONFIG_LV_USE_CALENDAR
|
||||
# define LV_USE_CALENDAR CONFIG_LV_USE_CALENDAR
|
||||
# else
|
||||
# define LV_USE_CALENDAR 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_CALENDAR
|
||||
#ifndef LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# ifdef CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# define LV_CALENDAR_WEEK_STARTS_MONDAY CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# else
|
||||
# define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#ifndef LV_USE_CANVAS
|
||||
# ifdef CONFIG_LV_USE_CANVAS
|
||||
@@ -1544,24 +1526,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#ifndef LV_USE_CONT
|
||||
# ifdef CONFIG_LV_USE_CONT
|
||||
# define LV_USE_CONT CONFIG_LV_USE_CONT
|
||||
# else
|
||||
# define LV_USE_CONT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#ifndef LV_USE_CPICKER
|
||||
# ifdef CONFIG_LV_USE_CPICKER
|
||||
# define LV_USE_CPICKER CONFIG_LV_USE_CPICKER
|
||||
# else
|
||||
# define LV_USE_CPICKER 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#ifndef LV_USE_DROPDOWN
|
||||
# ifdef CONFIG_LV_USE_DROPDOWN
|
||||
@@ -1618,15 +1582,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#ifndef LV_USE_KEYBOARD
|
||||
# ifdef CONFIG_LV_USE_KEYBOARD
|
||||
# define LV_USE_KEYBOARD CONFIG_LV_USE_KEYBOARD
|
||||
# else
|
||||
# define LV_USE_KEYBOARD 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#ifndef LV_USE_LABEL
|
||||
# ifdef CONFIG_LV_USE_LABEL
|
||||
@@ -1673,31 +1628,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#ifndef LV_USE_LED
|
||||
# ifdef CONFIG_LV_USE_LED
|
||||
# define LV_USE_LED CONFIG_LV_USE_LED
|
||||
# else
|
||||
# define LV_USE_LED 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_LED
|
||||
#ifndef LV_LED_BRIGHT_MIN
|
||||
# ifdef CONFIG_LV_LED_BRIGHT_MIN
|
||||
# define LV_LED_BRIGHT_MIN CONFIG_LV_LED_BRIGHT_MIN
|
||||
# else
|
||||
# define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/
|
||||
# endif
|
||||
#endif
|
||||
#ifndef LV_LED_BRIGHT_MAX
|
||||
# ifdef CONFIG_LV_LED_BRIGHT_MAX
|
||||
# define LV_LED_BRIGHT_MAX CONFIG_LV_LED_BRIGHT_MAX
|
||||
# else
|
||||
# define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#ifndef LV_USE_LINE
|
||||
# ifdef CONFIG_LV_USE_LINE
|
||||
@@ -1707,49 +1637,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#ifndef LV_USE_LIST
|
||||
# ifdef CONFIG_LV_USE_LIST
|
||||
# define LV_USE_LIST CONFIG_LV_USE_LIST
|
||||
# else
|
||||
# define LV_USE_LIST 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
#ifndef LV_LIST_DEF_ANIM_TIME
|
||||
# ifdef CONFIG_LV_LIST_DEF_ANIM_TIME
|
||||
# define LV_LIST_DEF_ANIM_TIME CONFIG_LV_LIST_DEF_ANIM_TIME
|
||||
# else
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#ifndef LV_USE_LINEMETER
|
||||
# ifdef CONFIG_LV_USE_LINEMETER
|
||||
# define LV_USE_LINEMETER CONFIG_LV_USE_LINEMETER
|
||||
# else
|
||||
# define LV_USE_LINEMETER 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_LINEMETER
|
||||
/* Draw line more precisely at cost of performance.
|
||||
* Useful if there are lot of lines any minor are visible
|
||||
* 0: No extra precision
|
||||
* 1: Some extra precision
|
||||
* 2: Best precision
|
||||
*/
|
||||
#ifndef LV_LINEMETER_PRECISE
|
||||
# ifdef CONFIG_LV_LINEMETER_PRECISE
|
||||
# define LV_LINEMETER_PRECISE CONFIG_LV_LINEMETER_PRECISE
|
||||
# else
|
||||
# define LV_LINEMETER_PRECISE 1
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Mask (dependencies: -)*/
|
||||
#ifndef LV_USE_OBJMASK
|
||||
# ifdef CONFIG_LV_USE_OBJMASK
|
||||
@@ -1759,66 +1646,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#ifndef LV_USE_MSGBOX
|
||||
# ifdef CONFIG_LV_USE_MSGBOX
|
||||
# define LV_USE_MSGBOX CONFIG_LV_USE_MSGBOX
|
||||
# else
|
||||
# define LV_USE_MSGBOX 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#ifndef LV_USE_PAGE
|
||||
# ifdef CONFIG_LV_USE_PAGE
|
||||
# define LV_USE_PAGE CONFIG_LV_USE_PAGE
|
||||
# else
|
||||
# define LV_USE_PAGE 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_PAGE_DEF_ANIM_TIME
|
||||
# ifdef CONFIG_LV_PAGE_DEF_ANIM_TIME
|
||||
# define LV_PAGE_DEF_ANIM_TIME CONFIG_LV_PAGE_DEF_ANIM_TIME
|
||||
# else
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#ifndef LV_USE_SPINNER
|
||||
# ifdef CONFIG_LV_USE_SPINNER
|
||||
# define LV_USE_SPINNER CONFIG_LV_USE_SPINNER
|
||||
# else
|
||||
# define LV_USE_SPINNER 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_SPINNER != 0
|
||||
#ifndef LV_SPINNER_DEF_ARC_LENGTH
|
||||
# ifdef CONFIG_LV_SPINNER_DEF_ARC_LENGTH
|
||||
# define LV_SPINNER_DEF_ARC_LENGTH CONFIG_LV_SPINNER_DEF_ARC_LENGTH
|
||||
# else
|
||||
# define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# endif
|
||||
#endif
|
||||
#ifndef LV_SPINNER_DEF_SPIN_TIME
|
||||
# ifdef CONFIG_LV_SPINNER_DEF_SPIN_TIME
|
||||
# define LV_SPINNER_DEF_SPIN_TIME CONFIG_LV_SPINNER_DEF_SPIN_TIME
|
||||
# else
|
||||
# define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# endif
|
||||
#endif
|
||||
#ifndef LV_SPINNER_DEF_ANIM
|
||||
# ifdef CONFIG_LV_SPINNER_DEF_ANIM
|
||||
# define LV_SPINNER_DEF_ANIM CONFIG_LV_SPINNER_DEF_ANIM
|
||||
# else
|
||||
# define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#ifndef LV_USE_ROLLER
|
||||
# ifdef CONFIG_LV_USE_ROLLER
|
||||
@@ -1856,15 +1683,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#ifndef LV_USE_SPINBOX
|
||||
# ifdef CONFIG_LV_USE_SPINBOX
|
||||
# define LV_USE_SPINBOX CONFIG_LV_USE_SPINBOX
|
||||
# else
|
||||
# define LV_USE_SPINBOX 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#ifndef LV_USE_SWITCH
|
||||
# ifdef CONFIG_LV_USE_SWITCH
|
||||
@@ -1925,53 +1743,6 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#endif
|
||||
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#ifndef LV_USE_TABVIEW
|
||||
# ifdef CONFIG_LV_USE_TABVIEW
|
||||
# define LV_USE_TABVIEW CONFIG_LV_USE_TABVIEW
|
||||
# else
|
||||
# define LV_USE_TABVIEW 1
|
||||
# endif
|
||||
#endif
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TABVIEW_DEF_ANIM_TIME
|
||||
# ifdef CONFIG_LV_TABVIEW_DEF_ANIM_TIME
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME CONFIG_LV_TABVIEW_DEF_ANIM_TIME
|
||||
# else
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#ifndef LV_USE_TILEVIEW
|
||||
# ifdef CONFIG_LV_USE_TILEVIEW
|
||||
# define LV_USE_TILEVIEW CONFIG_LV_USE_TILEVIEW
|
||||
# else
|
||||
# define LV_USE_TILEVIEW 1
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TILEVIEW_DEF_ANIM_TIME
|
||||
# ifdef CONFIG_LV_TILEVIEW_DEF_ANIM_TIME
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME CONFIG_LV_TILEVIEW_DEF_ANIM_TIME
|
||||
# else
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#ifndef LV_USE_WIN
|
||||
# ifdef CONFIG_LV_USE_WIN
|
||||
# define LV_USE_WIN CONFIG_LV_USE_WIN
|
||||
# else
|
||||
# define LV_USE_WIN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
CSRCS += lv_grid.c
|
||||
CSRCS += lv_group.c
|
||||
CSRCS += lv_indev.c
|
||||
CSRCS += lv_indev_scroll.c
|
||||
CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_obj_pos.c
|
||||
CSRCS += lv_obj_style.c
|
||||
CSRCS += lv_obj_draw.c
|
||||
CSRCS += lv_obj_scroll.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
|
||||
|
||||
@@ -229,8 +229,8 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
|
||||
/*Be sure both screens are in a normal position*/
|
||||
lv_obj_set_pos(new_scr, 0, 0);
|
||||
lv_obj_set_pos(lv_scr_act(), 0, 0);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(new_scr, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(lv_obj_get_local_style(lv_scr_act(), LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(_lv_obj_get_local_style(new_scr, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(_lv_obj_get_local_style(lv_scr_act(), LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
|
||||
lv_anim_t a_new;
|
||||
lv_anim_init(&a_new);
|
||||
@@ -403,6 +403,6 @@ static void scr_anim_ready(lv_anim_t * a)
|
||||
|
||||
if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr);
|
||||
d->prev_scr = NULL;
|
||||
lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
lv_style_remove_prop(_lv_obj_get_local_style(a->var, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
|
||||
}
|
||||
#endif
|
||||
|
||||
439
src/lv_core/lv_flex.c
Normal file
439
src/lv_core/lv_flex.c
Normal file
@@ -0,0 +1,439 @@
|
||||
/**
|
||||
* @file lv_flex.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_flex.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_coord_t grow_unit;
|
||||
lv_coord_t track_cross_size;
|
||||
lv_coord_t track_main_size;
|
||||
uint32_t item_cnt;
|
||||
}track_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
//static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_size, lv_coord_t * grow_unit, lv_coord_t * track_cross_size, lv_coord_t * track_main_size, uint32_t * item_cnt);
|
||||
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_main_size, track_t * t);
|
||||
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t);
|
||||
static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
|
||||
|
||||
static lv_flex_dir_t get_dir(const lv_obj_t * obj);
|
||||
static bool get_rev(const lv_obj_t * obj);
|
||||
static bool get_wrap(const lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
void lv_obj_set_flex_dir(lv_obj_t * obj, lv_flex_dir_t flex_dir)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(obj->spec_attr->flex_cont.dir == flex_dir) return;
|
||||
|
||||
obj->spec_attr->flex_cont.dir = flex_dir & 0x3;
|
||||
obj->spec_attr->flex_cont.wrap = flex_dir & _LV_FLEX_WRAP ? 1 : 0;
|
||||
obj->spec_attr->flex_cont.rev = flex_dir & _LV_FLEX_REVERSE ? 1 : 0;
|
||||
_lv_flex_refresh(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_flex_place(lv_obj_t * obj, lv_flex_place_t item_place, lv_flex_place_t track_place)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
if(obj->spec_attr->flex_cont.item_place == item_place &&
|
||||
obj->spec_attr->flex_cont.track_place == track_place) {
|
||||
return;
|
||||
}
|
||||
|
||||
obj->spec_attr->flex_cont.item_place = item_place;
|
||||
obj->spec_attr->flex_cont.track_place = track_place;
|
||||
|
||||
_lv_flex_refresh(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_flex_gap(lv_obj_t * obj, lv_coord_t gap)
|
||||
{
|
||||
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(obj->spec_attr->flex_cont.gap == gap) return;
|
||||
|
||||
obj->spec_attr->flex_cont.gap = gap;
|
||||
|
||||
_lv_flex_refresh(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_flex_item(lv_obj_t * obj, bool en)
|
||||
{
|
||||
if(en) {
|
||||
lv_coord_t f = _LV_COORD_FELX(LV_FLEX_PLACE_START);
|
||||
lv_obj_set_pos(obj, f, f);
|
||||
} else {
|
||||
lv_obj_set_pos(obj, lv_obj_get_x(obj), lv_obj_get_y(obj));
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_set_flex_item_place(lv_obj_t * obj, lv_flex_place_t place)
|
||||
{
|
||||
if(place == LV_FLEX_PLACE_NONE) {
|
||||
lv_obj_set_pos(obj, lv_obj_get_x(obj), lv_obj_get_x(obj));
|
||||
} else {
|
||||
lv_coord_t f = _LV_COORD_FELX(place);
|
||||
lv_obj_set_pos(obj, f, f);
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_flex_dir_t lv_obj_get_flex_dir(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.dir;
|
||||
else return LV_FLEX_DIR_NONE;
|
||||
}
|
||||
|
||||
lv_flex_place_t lv_obj_get_flex_item_place(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.item_place;
|
||||
else return LV_FLEX_PLACE_START;
|
||||
}
|
||||
|
||||
lv_flex_place_t lv_obj_get_flex_track_place(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.track_place;
|
||||
else return LV_FLEX_PLACE_START;
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_flex_gap(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.gap;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
lv_flex_place_t lv_obj_get_flex_self_place(lv_obj_t * obj)
|
||||
{
|
||||
lv_coord_t x = lv_obj_get_x(obj);
|
||||
if(LV_COORD_IS_FLEX(x)) return LV_COORD_GET_FLEX(x);
|
||||
else return LV_FLEX_PLACE_NONE;
|
||||
}
|
||||
|
||||
void _lv_flex_refresh(lv_obj_t * cont)
|
||||
{
|
||||
lv_flex_dir_t dir = get_dir(cont);
|
||||
|
||||
if(dir == LV_FLEX_DIR_NONE) return;
|
||||
|
||||
bool rtl = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false;
|
||||
bool row = dir == LV_FLEX_DIR_ROW ? true : false;
|
||||
/*Count the grow units and free space*/
|
||||
lv_coord_t max_main_size = (row ? lv_obj_get_width_fit(cont) : lv_obj_get_height_fit(cont));
|
||||
lv_coord_t abs_y = cont->coords.y1 + lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN) - lv_obj_get_scroll_y(cont);
|
||||
lv_coord_t abs_x = cont->coords.x1 + lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN) - lv_obj_get_scroll_x(cont);
|
||||
|
||||
lv_flex_place_t cross_place = lv_obj_get_flex_track_place(cont);
|
||||
lv_flex_place_t main_place = cont->spec_attr->flex_cont.item_place;
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
|
||||
lv_coord_t * cross_pos = (row ? &abs_y : &abs_x);
|
||||
|
||||
if((row && cont->h_set == LV_SIZE_AUTO) ||
|
||||
(!row && cont->w_set == LV_SIZE_AUTO))
|
||||
{
|
||||
cross_place = LV_FLEX_PLACE_START;
|
||||
}
|
||||
|
||||
if(rtl && !row) {
|
||||
if(cross_place == LV_FLEX_PLACE_START) cross_place = LV_FLEX_PLACE_END;
|
||||
else if(cross_place == LV_FLEX_PLACE_END) cross_place = LV_FLEX_PLACE_START;
|
||||
}
|
||||
|
||||
lv_coord_t total_track_cross_size = 0;
|
||||
lv_coord_t gap = 0;
|
||||
uint32_t track_cnt = 0;
|
||||
lv_obj_t * track_first_item;
|
||||
lv_obj_t * next_track_first_item;
|
||||
bool rev = get_rev(cont);
|
||||
|
||||
if(cross_place != LV_FLEX_PLACE_START) {
|
||||
track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll);
|
||||
track_t t;
|
||||
while(track_first_item) {
|
||||
/*Search the first item of the next row */
|
||||
next_track_first_item = find_track_end(cont, track_first_item, max_main_size, &t);
|
||||
total_track_cross_size += t.track_cross_size;
|
||||
track_cnt++;
|
||||
track_first_item = next_track_first_item;
|
||||
}
|
||||
|
||||
lv_coord_t max_cross_size = (row ? lv_obj_get_height_fit(cont) : lv_obj_get_width_fit(cont));
|
||||
place_content(cross_place, max_cross_size, total_track_cross_size, track_cnt, cross_pos, &gap);
|
||||
}
|
||||
|
||||
track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll);
|
||||
|
||||
if(rtl && !row) {
|
||||
*cross_pos += total_track_cross_size;
|
||||
}
|
||||
|
||||
while(track_first_item) {
|
||||
track_t t;
|
||||
/*Search the first item of the next row */
|
||||
next_track_first_item = find_track_end(cont, track_first_item, max_main_size, &t);
|
||||
|
||||
if(rtl && !row) {
|
||||
*cross_pos -= t.track_cross_size;
|
||||
}
|
||||
children_repos(cont, track_first_item, next_track_first_item, abs_x, abs_y, max_main_size, main_place, &t);
|
||||
track_first_item = next_track_first_item;
|
||||
|
||||
if(rtl && !row) {
|
||||
*cross_pos -= gap;
|
||||
} else {
|
||||
*cross_pos += t.track_cross_size + gap;
|
||||
}
|
||||
}
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_main_size, track_t * t)
|
||||
{
|
||||
bool wrap = get_wrap(cont);
|
||||
bool rev = get_rev(cont);
|
||||
lv_coord_t gap = lv_obj_get_flex_gap(cont);
|
||||
bool row = get_dir(cont) == LV_FLEX_DIR_ROW ? true : false;
|
||||
lv_coord_t(*get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
lv_coord_t(*get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _lv_ll_get_next : _lv_ll_get_prev;
|
||||
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
|
||||
|
||||
lv_coord_t grow_sum = 0;
|
||||
t->track_main_size = 0;
|
||||
uint32_t grow_item_cnt = 0;
|
||||
t->track_cross_size = 0;
|
||||
t->grow_unit = 0;
|
||||
t->item_cnt = 0;
|
||||
|
||||
lv_obj_t * item = item_start;
|
||||
while(item) {
|
||||
/*Ignore non-flex items*/
|
||||
lv_coord_t main_set = (row ? item->x_set : item->y_set);
|
||||
if(LV_COORD_IS_FLEX(main_set) == false) {
|
||||
item = ll_iter(ll, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_coord_t main_size = (row ? item->w_set : item->h_set);
|
||||
if(_LV_FLEX_GET_GROW(main_size)) {
|
||||
grow_sum += _LV_FLEX_GET_GROW(main_size);
|
||||
grow_item_cnt++;
|
||||
} else {
|
||||
lv_coord_t item_size = get_main_size(item) + gap;
|
||||
if(wrap && t->track_main_size + item_size > max_main_size) break;
|
||||
t->track_main_size += item_size;
|
||||
}
|
||||
t->track_cross_size = LV_MATH_MAX(get_cross_size(item), t->track_cross_size);
|
||||
|
||||
item = ll_iter(ll, item);
|
||||
t->item_cnt++;
|
||||
}
|
||||
|
||||
if(t->track_main_size > 0) t->track_main_size -= gap; /*There is no gap after the last item*/
|
||||
|
||||
if(grow_item_cnt && grow_sum) {
|
||||
lv_coord_t s = max_main_size - t->track_main_size;
|
||||
s -= grow_item_cnt * gap;
|
||||
t->grow_unit = s / grow_sum;
|
||||
t->track_main_size = max_main_size; /*If there is at least one "grow item" the track takes the full space*/
|
||||
} else {
|
||||
t->grow_unit = 0;
|
||||
}
|
||||
|
||||
/*Have at least one item in a row*/
|
||||
if(item && item == item_start) {
|
||||
item = ll_iter(ll, item);
|
||||
if(item) {
|
||||
t->track_cross_size = get_cross_size(item);
|
||||
t->track_main_size = get_main_size(item);
|
||||
t->item_cnt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t)
|
||||
{
|
||||
bool rev = get_rev(cont);
|
||||
lv_coord_t gap = lv_obj_get_flex_gap(cont);
|
||||
bool row = get_dir(cont) == LV_FLEX_DIR_ROW ? true : false;
|
||||
|
||||
lv_coord_t(*obj_get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
lv_coord_t(*obj_get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
void (*area_set_main_size)(lv_area_t *, lv_coord_t) = (row ? lv_area_set_width : lv_area_set_height);
|
||||
void (*area_set_cross_size)(lv_area_t *, lv_coord_t) = (!row ? lv_area_set_width : lv_area_set_height);
|
||||
lv_coord_t (*area_get_main_size)(const lv_area_t *) = (!row ? lv_area_get_width : lv_area_get_height);
|
||||
lv_style_int_t (*get_margin_start)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top);
|
||||
lv_style_int_t (*get_margin_end)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom);
|
||||
void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _lv_ll_get_next : _lv_ll_get_prev;
|
||||
|
||||
bool rtl = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false;
|
||||
|
||||
if(row && rtl) abs_x += lv_obj_get_width_fit(cont);
|
||||
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
|
||||
lv_coord_t main_pos = 0;
|
||||
|
||||
lv_coord_t place_gap;
|
||||
place_content(main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap);
|
||||
/*Reposition the children*/
|
||||
lv_obj_t * item = item_first; /*Just to use a shorter name*/
|
||||
while(item != item_last) {
|
||||
|
||||
/*Ignore non-flex items*/
|
||||
lv_coord_t main_set = (row ? item->x_set : item->y_set);
|
||||
if(LV_COORD_IS_FLEX(main_set) == false) {
|
||||
item = ll_iter(ll, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_coord_t main_size = (row ? item->w_set : item->h_set);
|
||||
if(_LV_FLEX_GET_GROW(main_size) || LV_COORD_GET_FLEX(main_set) == LV_FLEX_PLACE_STRETCH) {
|
||||
lv_area_t old_coords;
|
||||
lv_area_copy(&old_coords, &item->coords);
|
||||
|
||||
if(_LV_FLEX_GET_GROW(main_size)) {
|
||||
lv_coord_t s = _LV_FLEX_GET_GROW(main_size) * t->grow_unit;
|
||||
s -= get_margin_start(item, LV_OBJ_PART_MAIN) + get_margin_end(item, LV_OBJ_PART_MAIN);
|
||||
area_set_main_size(&item->coords, s);
|
||||
}
|
||||
if(LV_COORD_GET_FLEX(main_set) == LV_FLEX_PLACE_STRETCH) {
|
||||
area_set_cross_size(&item->coords, t->track_cross_size);
|
||||
}
|
||||
|
||||
if(lv_area_get_height(&old_coords) != area_get_main_size(&item->coords)) {
|
||||
lv_obj_invalidate(item);
|
||||
item->signal_cb(item, LV_SIGNAL_COORD_CHG, &old_coords);
|
||||
lv_obj_invalidate(item);
|
||||
}
|
||||
}
|
||||
|
||||
lv_coord_t cross_pos = 0;
|
||||
lv_coord_t cross_set = (row ? item->y_set : item->x_set);
|
||||
switch(LV_COORD_GET_FLEX(cross_set)) {
|
||||
case LV_FLEX_PLACE_CENTER:
|
||||
cross_pos = (t->track_cross_size - obj_get_cross_size(item)) / 2;
|
||||
break;
|
||||
case LV_FLEX_PLACE_END:
|
||||
cross_pos = t->track_cross_size - obj_get_cross_size(item);
|
||||
break;
|
||||
}
|
||||
|
||||
if(row && rtl) {
|
||||
main_pos -= obj_get_main_size(item) + gap + place_gap;
|
||||
}
|
||||
|
||||
lv_coord_t diff_x = abs_x - item->coords.x1 + lv_obj_get_style_margin_left(item, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t diff_y = abs_y - item->coords.y1 + lv_obj_get_style_margin_top(item, LV_OBJ_PART_MAIN);
|
||||
diff_x += row ? main_pos : cross_pos;
|
||||
diff_y += row ? cross_pos : main_pos;
|
||||
|
||||
if(diff_x || diff_y) {
|
||||
item->coords.x1 += diff_x;
|
||||
item->coords.x2 += diff_x;
|
||||
item->coords.y1 += diff_y;
|
||||
item->coords.y2 += diff_y;
|
||||
_lv_obj_move_children_by(item, diff_x, diff_y);
|
||||
}
|
||||
|
||||
if(!(row && rtl)) {
|
||||
main_pos += obj_get_main_size(item) + gap + place_gap;
|
||||
}
|
||||
item = ll_iter(ll, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap)
|
||||
{
|
||||
if(item_cnt <= 1) {
|
||||
switch(place) {
|
||||
case LV_FLEX_PLACE_SPACE_BETWEEN:
|
||||
case LV_FLEX_PLACE_SPACE_AROUND:
|
||||
case LV_FLEX_PLACE_SPACE_EVENLY:
|
||||
place = LV_FLEX_PLACE_CENTER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(place) {
|
||||
case LV_FLEX_PLACE_CENTER:
|
||||
*gap = 0;
|
||||
*start_pos += (max_size - track_size) / 2;
|
||||
break;
|
||||
case LV_FLEX_PLACE_END:
|
||||
*gap = 0;
|
||||
*start_pos += max_size - track_size;
|
||||
break;
|
||||
case LV_FLEX_PLACE_SPACE_BETWEEN:
|
||||
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt - 1);
|
||||
break;
|
||||
case LV_FLEX_PLACE_SPACE_AROUND:
|
||||
*gap += (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt);
|
||||
*start_pos += *gap / 2;
|
||||
break;
|
||||
case LV_FLEX_PLACE_SPACE_EVENLY:
|
||||
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt + 1);
|
||||
*start_pos += *gap;
|
||||
break;
|
||||
default:
|
||||
*gap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static lv_flex_dir_t get_dir(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.dir;
|
||||
else return false;
|
||||
}
|
||||
|
||||
static bool get_rev(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.rev;
|
||||
else return false;
|
||||
}
|
||||
|
||||
static bool get_wrap(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->flex_cont.wrap;
|
||||
else return false;
|
||||
}
|
||||
162
src/lv_core/lv_flex.h
Normal file
162
src/lv_core/lv_flex.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* @file lv_flex.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FLEX_H
|
||||
#define LV_FLEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Can be set as width or height (on main axis) to grow the object in order fill the free space*/
|
||||
#define LV_FLEX_GROW(grow) (_LV_COORD_FELX(grow))
|
||||
|
||||
#define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_FLEX(v) ? LV_COORD_GET_FLEX(v) : 0)
|
||||
|
||||
#define _LV_FLEX_WRAP (1 << 2)
|
||||
#define _LV_FLEX_REVERSE (1 << 3)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* Can't include lv_obj.h because it includes this header file */
|
||||
struct _lv_obj_t;
|
||||
|
||||
typedef enum {
|
||||
LV_FLEX_PLACE_NONE,
|
||||
LV_FLEX_PLACE_START,
|
||||
LV_FLEX_PLACE_END,
|
||||
LV_FLEX_PLACE_CENTER,
|
||||
LV_FLEX_PLACE_STRETCH,
|
||||
LV_FLEX_PLACE_SPACE_EVENLY,
|
||||
LV_FLEX_PLACE_SPACE_AROUND,
|
||||
LV_FLEX_PLACE_SPACE_BETWEEN,
|
||||
}lv_flex_place_t;
|
||||
|
||||
typedef enum {
|
||||
LV_FLEX_DIR_NONE,
|
||||
LV_FLEX_DIR_ROW = 0x01,
|
||||
LV_FLEX_DIR_COLUMN = 0x02,
|
||||
LV_FLEX_DIR_ROW_WRAP = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP,
|
||||
LV_FLEX_DIR_ROW_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_REVERSE,
|
||||
LV_FLEX_DIR_ROW_WRAP_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
|
||||
LV_FLEX_DIR_COLUMN_WRAP = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP,
|
||||
LV_FLEX_DIR_COLUMN_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_REVERSE,
|
||||
LV_FLEX_DIR_COLUMN_WRAP_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
|
||||
}lv_flex_dir_t;
|
||||
|
||||
typedef struct {
|
||||
lv_coord_t gap;
|
||||
uint8_t dir :2;
|
||||
uint8_t wrap :1;
|
||||
uint8_t rev :1;
|
||||
uint8_t item_place :3;
|
||||
uint8_t track_place :3;
|
||||
}lv_flex_cont_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Makes an object a flex container by setting the direction of the layout.
|
||||
* The children explicitly needs to be made flex items with
|
||||
* `lv_obj_set_flex_item()` or `lv_obj_set_flex_item_place()`
|
||||
* @param obj pointer to an object
|
||||
* @param flex_dir the flex direction, an element of `lv_flex_dir_t`
|
||||
*/
|
||||
void lv_obj_set_flex_dir(struct _lv_obj_t * obj, lv_flex_dir_t flex_dir);
|
||||
|
||||
/**
|
||||
* Set how to place the items and the tracks
|
||||
* @param obj point to a flex container
|
||||
* @param item_place tells how to distribute the free space among the items in the same track
|
||||
* @param track_place tells how to distribute the free space among the tracks
|
||||
* @note if the base direction is RTL and the direction is ROW, LV_FLEX_START means the right side
|
||||
*/
|
||||
void lv_obj_set_flex_place(struct _lv_obj_t * obj, lv_flex_place_t item_place, lv_flex_place_t track_place);
|
||||
|
||||
/**
|
||||
* Make an object flex item, i.e. allow setting it's coordinate according to the parent's flex settings.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_set_flex_item(struct _lv_obj_t * obj, bool en);
|
||||
|
||||
/**
|
||||
* Set how the place the item in it's track in the cross direction.
|
||||
* It has a visible effect only if the objects in the same track has different size in the cross direction.
|
||||
* For ROW direction it means how to place the objects vertically in their row.
|
||||
* For COLUMN direction it means how to place the objects horizontally in their column.
|
||||
* @param obj pointer to a flex item
|
||||
* @param place:
|
||||
* - `LV_FLEX_PLACE_START` top/left (in case of RTL base direction right)
|
||||
* - `LV_FLEX_PLACE_CENTER` center
|
||||
* - `LV_FLEX_PLACE_END` bottom/right (in case of RTL base direction left)
|
||||
*/
|
||||
void lv_obj_set_flex_item_place(struct _lv_obj_t * obj, lv_flex_place_t place);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the flex direction of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the flex direction of `obj`
|
||||
*/
|
||||
lv_flex_dir_t lv_obj_get_flex_dir(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the item placement of a flex container
|
||||
* @param obj pointer to an object
|
||||
* @return the item placement
|
||||
*/
|
||||
lv_flex_place_t lv_obj_get_flex_item_place(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the track placement of a flex container
|
||||
* @param obj pointer to an object
|
||||
* @return the track placement
|
||||
*/
|
||||
lv_flex_place_t lv_obj_get_flex_track_place(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get how the flex item is placed in its track in the cross direction.
|
||||
* For ROW direction it means how the item is placed vertically in its row.
|
||||
* For COLUMN direction it means how the item is placed horizontally in its column.
|
||||
* @param obj pointer to a flex item
|
||||
* @return `LV_FLEX_PLACE_NONE/START/CENTER/END`
|
||||
*/
|
||||
lv_flex_place_t lv_obj_get_flex_self_place(struct _lv_obj_t * obj);
|
||||
/**
|
||||
* Rearrange the flex items of a flex container
|
||||
* @param cont pointer to a flex container object
|
||||
*/
|
||||
void _lv_flex_refresh(struct _lv_obj_t * cont);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_FLEX_H*/
|
||||
538
src/lv_core/lv_grid.c
Normal file
538
src/lv_core/lv_grid.c
Normal file
@@ -0,0 +1,538 @@
|
||||
/**
|
||||
* @file lv_align.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_grid.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_obj"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
uint32_t col;
|
||||
uint32_t row;
|
||||
lv_point_t grid_abs;
|
||||
}item_repos_hint_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc);
|
||||
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc);
|
||||
static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint);
|
||||
static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t place, lv_coord_t gap, uint32_t track_num, lv_coord_t * size_array, lv_coord_t * pos_array, bool reverse);
|
||||
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_grid_init(lv_grid_t * grid)
|
||||
{
|
||||
_lv_memset_00(grid,sizeof(lv_grid_t));
|
||||
grid->col_place = LV_GRID_START;
|
||||
grid->row_place = LV_GRID_START;
|
||||
}
|
||||
|
||||
void lv_grid_set_template(lv_grid_t * grid, const lv_coord_t * col_dsc, uint8_t col_cnt, const lv_coord_t * row_dsc, uint8_t row_cnt)
|
||||
{
|
||||
grid->col_dsc = col_dsc;
|
||||
grid->col_dsc_len = col_cnt;
|
||||
grid->row_dsc = row_dsc;
|
||||
grid->row_dsc_len = row_cnt;
|
||||
}
|
||||
|
||||
|
||||
void lv_grid_set_place(lv_grid_t * grid, uint8_t col_place, uint8_t row_place)
|
||||
{
|
||||
grid->col_place = col_place;
|
||||
grid->row_place = row_place;
|
||||
}
|
||||
|
||||
void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap)
|
||||
{
|
||||
grid->col_gap = col_gap;
|
||||
grid->row_gap = row_gap;
|
||||
|
||||
}
|
||||
/**
|
||||
* Set a grid for an object
|
||||
* @param obj pointer to an object
|
||||
* @param grid the grid to set
|
||||
*/
|
||||
void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->grid = grid;
|
||||
|
||||
_lv_grid_full_refresh(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grid of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the grid, NULL if no grid
|
||||
*/
|
||||
const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
if(obj->spec_attr) return obj->spec_attr->grid;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos)
|
||||
{
|
||||
lv_obj_set_pos(obj, col_pos, row_pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all object if a style is modified
|
||||
* @param grid pointer to a grid. Only the objects with this grid will be notified
|
||||
* (NULL to notify all objects with any grid)
|
||||
*/
|
||||
void lv_obj_report_grid_change(const lv_grid_t * grid)
|
||||
{
|
||||
lv_disp_t * d = lv_disp_get_next(NULL);
|
||||
|
||||
while(d) {
|
||||
lv_obj_t * i;
|
||||
_LV_LL_READ(&d->scr_ll, i) {
|
||||
report_grid_change_core(grid, i);
|
||||
}
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the grid cells coordinates
|
||||
* @param cont an object that has a grid
|
||||
* @param calc store the calculated cells sizes here
|
||||
* @note `_lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore
|
||||
*/
|
||||
void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
|
||||
{
|
||||
lv_grid_t * g = lv_obj_get_grid(cont);
|
||||
if(g == NULL) return;
|
||||
if(g->col_dsc == NULL || g->row_dsc == NULL) return;
|
||||
if(g->col_dsc_len == 0 || g->row_dsc_len == 0) return;
|
||||
|
||||
if(lv_obj_get_child(cont, NULL) == NULL) {
|
||||
_lv_memset_00(calc_out, sizeof(_lv_grid_calc_t));
|
||||
return;
|
||||
}
|
||||
// printf("calc: %d, %d\n", obj->grid->col_dsc_len, obj->grid->row_dsc_len);
|
||||
|
||||
calc_rows(cont, calc_out);
|
||||
calc_cols(cont, calc_out);
|
||||
|
||||
bool rev = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false;
|
||||
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(cont);
|
||||
calc_out->grid_w = grid_place(cont_w, auto_w, g->col_place, g->col_gap, calc_out->col_num, calc_out->w, calc_out->x, rev);
|
||||
|
||||
bool auto_h = cont->h_set == LV_SIZE_AUTO ? true : false;
|
||||
lv_coord_t cont_h = lv_obj_get_height_fit(cont);
|
||||
calc_out->grid_h = grid_place(cont_h, auto_h, g->row_place, g->row_gap, calc_out->row_num, calc_out->h, calc_out->y, false);
|
||||
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the a grid calculation's data
|
||||
* @param calc pointer to the calculated gtrid cell coordinates
|
||||
*/
|
||||
void _lv_grid_calc_free(_lv_grid_calc_t * calc)
|
||||
{
|
||||
_lv_mem_buf_release(calc->x);
|
||||
_lv_mem_buf_release(calc->y);
|
||||
_lv_mem_buf_release(calc->w);
|
||||
_lv_mem_buf_release(calc->h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the object's grid columns has FR cells or not
|
||||
* @param obj pointer to an object
|
||||
* @return true: has FR; false: has no FR
|
||||
*/
|
||||
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_grid_t * g = lv_obj_get_grid(obj);
|
||||
if(g->col_dsc == NULL) return false;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < g->col_dsc_len; i++) {
|
||||
if(LV_GRID_IS_FR(g->col_dsc[i])) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the object's grid rows has FR cells or not
|
||||
* @param obj pointer to an object
|
||||
* @return true: has FR; false: has no FR
|
||||
*/
|
||||
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_grid_t * g = lv_obj_get_grid(obj);
|
||||
if(g == NULL) return false;
|
||||
if(g->row_dsc == NULL) return false;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < g->row_dsc_len; i++) {
|
||||
if(LV_GRID_IS_FR(g->row_dsc[i])) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the all grid item on a container
|
||||
* @param cont pointer to a grid container object
|
||||
*/
|
||||
void _lv_grid_full_refresh(lv_obj_t * cont)
|
||||
{
|
||||
/*Calculate the grid*/
|
||||
if(lv_obj_get_grid(cont) == NULL) return;
|
||||
_lv_grid_calc_t calc;
|
||||
_lv_grid_calc(cont, &calc);
|
||||
|
||||
|
||||
item_repos_hint_t hint;
|
||||
_lv_memset_00(&hint, sizeof(hint));
|
||||
|
||||
/* Calculate the grids absolute x and y coordinates.
|
||||
* It will be used as helper during item repositioning to avoid calculating this value for every children*/
|
||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN);
|
||||
hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_x(cont);
|
||||
hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_y(cont);
|
||||
|
||||
lv_obj_t * item = lv_obj_get_child_back(cont, NULL);
|
||||
while(item) {
|
||||
if(LV_COORD_IS_GRID(item->x_set) && LV_COORD_IS_GRID(item->y_set)) {
|
||||
item_repos(cont, item, &calc, &hint);
|
||||
}
|
||||
item = lv_obj_get_child_back(cont, item);
|
||||
}
|
||||
_lv_grid_calc_free(&calc);
|
||||
|
||||
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
|
||||
lv_obj_set_size(cont, cont->w_set, cont->h_set);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the position of a grid item
|
||||
* @param item pointer to a grid item
|
||||
*/
|
||||
void lv_grid_item_refr_pos(lv_obj_t * item)
|
||||
{
|
||||
/*Calculate the grid*/
|
||||
lv_obj_t * cont = lv_obj_get_parent(item);
|
||||
if(cont == NULL) return;
|
||||
if(cont->spec_attr == NULL) return;
|
||||
if(cont->spec_attr->grid == NULL) return;
|
||||
_lv_grid_calc_t calc;
|
||||
_lv_grid_calc(cont, &calc);
|
||||
|
||||
item_repos(cont, item, &calc, NULL);
|
||||
|
||||
_lv_grid_calc_free(&calc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
|
||||
{
|
||||
const lv_grid_t * grid = cont->spec_attr->grid;
|
||||
uint32_t i;
|
||||
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(cont);
|
||||
|
||||
calc->col_num = grid->col_dsc_len;
|
||||
calc->x = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num);
|
||||
calc->w = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num);
|
||||
|
||||
uint32_t col_fr_cnt = 0;
|
||||
lv_coord_t grid_w = 0;
|
||||
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
|
||||
|
||||
for(i = 0; i < calc->col_num; i++) {
|
||||
lv_coord_t x = grid->col_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) col_fr_cnt += LV_GRID_GET_FR(x);
|
||||
else {
|
||||
calc->w[i] = x;
|
||||
grid_w += x;
|
||||
}
|
||||
}
|
||||
|
||||
cont_w -= grid->col_gap * (calc->col_num - 1);
|
||||
lv_coord_t free_w = cont_w - grid_w;
|
||||
|
||||
for(i = 0; i < calc->col_num; i++) {
|
||||
lv_coord_t x = grid->col_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) {
|
||||
if(auto_w) calc->w[i] = 0; /*Fr is considered zero if the cont has auto width*/
|
||||
else {
|
||||
lv_coord_t f = LV_GRID_GET_FR(x);
|
||||
calc->w[i] = (free_w * f) / col_fr_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
|
||||
{
|
||||
const lv_grid_t * grid = cont->spec_attr->grid;
|
||||
uint32_t i;
|
||||
|
||||
calc->row_num = grid->row_dsc_len;
|
||||
calc->y = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num);
|
||||
calc->h = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num);
|
||||
|
||||
uint32_t row_fr_cnt = 0;
|
||||
lv_coord_t grid_h = 0;
|
||||
|
||||
bool auto_h = cont->h_set == LV_SIZE_AUTO ? true : false;
|
||||
|
||||
|
||||
for(i = 0; i < grid->row_dsc_len; i++) {
|
||||
lv_coord_t x = grid->row_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) row_fr_cnt += LV_GRID_GET_FR(x);
|
||||
else {
|
||||
calc->h[i] = x;
|
||||
grid_h += x;
|
||||
}
|
||||
}
|
||||
|
||||
lv_coord_t cont_h = lv_obj_get_height_fit(cont) - grid->row_gap * (grid->row_dsc_len - 1);
|
||||
lv_coord_t free_h = cont_h - grid_h;
|
||||
|
||||
for(i = 0; i < grid->row_dsc_len; i++) {
|
||||
lv_coord_t x = grid->row_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) {
|
||||
if(auto_h) calc->h[i] = 0; /*Fr is considered zero if the obj has auto height*/
|
||||
else {
|
||||
lv_coord_t f = LV_GRID_GET_FR(x);
|
||||
calc->h[i] = (free_h * f) / row_fr_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reposition a grid item in its cell
|
||||
* @param cont a grid container object
|
||||
* @param item a grid item to reposition
|
||||
* @param calc the calculated grid of `cont`
|
||||
* @param child_id_ext helper value if the ID of the child is know (order from the oldest) else -1
|
||||
* @param grid_abs helper value, the absolute position of the grid, NULL if unknown
|
||||
*/
|
||||
static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint)
|
||||
{
|
||||
if(_lv_obj_is_grid_item(item) == false) return;
|
||||
|
||||
uint32_t col_pos = LV_GRID_GET_CELL_POS(item->x_set);
|
||||
uint32_t col_span = LV_GRID_GET_CELL_SPAN(item->x_set);
|
||||
uint32_t row_pos = LV_GRID_GET_CELL_POS(item->y_set);
|
||||
uint32_t row_span = LV_GRID_GET_CELL_SPAN(item->y_set);
|
||||
|
||||
lv_coord_t col_x1 = calc->x[col_pos];
|
||||
lv_coord_t col_x2 = calc->x[col_pos + col_span - 1] + calc->w[col_pos + col_span - 1];
|
||||
lv_coord_t col_w = col_x2 - col_x1;
|
||||
|
||||
lv_coord_t row_y1 = calc->y[row_pos];
|
||||
lv_coord_t row_y2 = calc->y[row_pos + row_span - 1] + calc->h[row_pos + row_span - 1];
|
||||
lv_coord_t row_h = row_y2 - row_y1;
|
||||
|
||||
uint8_t x_flag = LV_GRID_GET_CELL_PLACE(item->x_set);
|
||||
uint8_t y_flag = LV_GRID_GET_CELL_PLACE(item->y_set);
|
||||
|
||||
/*If the item has RTL base dir switch start and end*/
|
||||
if(lv_obj_get_base_dir(item) == LV_BIDI_DIR_RTL) {
|
||||
if(x_flag == LV_GRID_START) x_flag = LV_GRID_END;
|
||||
else if(x_flag == LV_GRID_END) x_flag = LV_GRID_START;
|
||||
}
|
||||
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
lv_coord_t item_w = lv_obj_get_width(item);
|
||||
lv_coord_t item_h = lv_obj_get_height(item);
|
||||
|
||||
lv_coord_t margin_top = lv_obj_get_style_margin_top(item, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t margin_bottom = lv_obj_get_style_margin_bottom(item, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t margin_left = lv_obj_get_style_margin_left(item, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t margin_right = lv_obj_get_style_margin_right(item, LV_OBJ_PART_MAIN);
|
||||
|
||||
switch(x_flag) {
|
||||
case LV_GRID_START:
|
||||
x = calc->x[col_pos] + margin_left;
|
||||
break;
|
||||
case LV_GRID_STRETCH:
|
||||
x = calc->x[col_pos] + margin_left;
|
||||
item_w = col_w - margin_left - margin_right;
|
||||
item->w_set = LV_SIZE_STRETCH;
|
||||
break;
|
||||
case LV_GRID_CENTER:
|
||||
x = calc->x[col_pos] + (col_w - (item_w + margin_left - margin_right)) / 2;
|
||||
break;
|
||||
case LV_GRID_END:
|
||||
x = calc->x[col_pos] + col_w - lv_obj_get_width(item) - margin_right;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(y_flag) {
|
||||
case LV_GRID_START:
|
||||
y = calc->y[row_pos] + margin_top;
|
||||
break;
|
||||
case LV_GRID_STRETCH:
|
||||
y = calc->y[row_pos] + margin_top;
|
||||
item_h = row_h - margin_top - margin_bottom;
|
||||
item->h_set = LV_SIZE_STRETCH;
|
||||
break;
|
||||
case LV_GRID_CENTER:
|
||||
y = calc->y[row_pos] + (row_h - (item_h + margin_top + margin_bottom)) / 2;
|
||||
break;
|
||||
case LV_GRID_END:
|
||||
y = calc->y[row_pos] + row_h - lv_obj_get_height(item) - margin_bottom;
|
||||
break;
|
||||
}
|
||||
|
||||
/*Set a new size if required*/
|
||||
if(lv_obj_get_width(item) != item_w || lv_obj_get_height(item) != item_h) {
|
||||
lv_area_t old_coords;
|
||||
lv_area_copy(&old_coords, &item->coords);
|
||||
lv_obj_invalidate(item);
|
||||
lv_area_set_width(&item->coords, item_w);
|
||||
lv_area_set_height(&item->coords, item_h);
|
||||
lv_obj_invalidate(item);
|
||||
item->signal_cb(item, LV_SIGNAL_COORD_CHG, &old_coords);
|
||||
|
||||
}
|
||||
bool moved = true;
|
||||
if(hint) {
|
||||
if(hint->grid_abs.x + x == item->coords.x1 && hint->grid_abs.y + y == item->coords.y1) moved = false;
|
||||
}
|
||||
|
||||
if(moved) _lv_obj_move_to(item, x, y, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Place the grid track according to place methods. It keeps the track sizes but sets their position.
|
||||
* It can process both columns or rows according to the passed parameters.
|
||||
* @param cont_size size of the containers content area (width/height)
|
||||
* @param auto_size true: the container has auto size in the current direction
|
||||
* @param place placeing method
|
||||
* @param gap grid gap
|
||||
* @param track_num number of tracks
|
||||
* @param size_array array with the track sizes
|
||||
* @param pos_array write the positions of the tracks here
|
||||
* @return the total size of the grid
|
||||
*/
|
||||
static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t place, lv_coord_t gap, uint32_t track_num, lv_coord_t * size_array, lv_coord_t * pos_array, bool reverse)
|
||||
{
|
||||
lv_coord_t grid_size = 0;
|
||||
int32_t i;
|
||||
|
||||
if(auto_size) {
|
||||
pos_array[0] = 0;
|
||||
} else {
|
||||
/*With spaced placements gap will be calculated from the remaining space*/
|
||||
if(place == LV_GRID_SPACE_AROUND || place == LV_GRID_SPACE_BETWEEN || place == LV_GRID_SPACE_EVENLY) {
|
||||
gap = 0;
|
||||
if(track_num == 1) place = LV_GRID_CENTER;
|
||||
}
|
||||
|
||||
/*Get the full grid size with gap*/
|
||||
for(i = 0; i < track_num; i++) {
|
||||
grid_size += size_array[i] + gap;
|
||||
}
|
||||
grid_size -= gap;
|
||||
|
||||
/*Calculate the position of the first item and set gap is necessary*/
|
||||
switch(place) {
|
||||
case LV_GRID_START:
|
||||
pos_array[0] = 0;
|
||||
break;
|
||||
case LV_GRID_CENTER:
|
||||
pos_array[0] = (cont_size - grid_size) / 2;
|
||||
break;
|
||||
case LV_GRID_END:
|
||||
pos_array[0] = cont_size - grid_size;
|
||||
break;
|
||||
case LV_GRID_SPACE_BETWEEN:
|
||||
pos_array[0] = 0;
|
||||
gap = (lv_coord_t)(cont_size - grid_size) / (lv_coord_t)(track_num - 1);
|
||||
break;
|
||||
case LV_GRID_SPACE_AROUND:
|
||||
gap = (lv_coord_t)(cont_size - grid_size) / (lv_coord_t)(track_num);
|
||||
pos_array[0] = gap / 2;
|
||||
break;
|
||||
case LV_GRID_SPACE_EVENLY:
|
||||
gap = (lv_coord_t)(cont_size - grid_size) / (lv_coord_t)(track_num + 1);
|
||||
pos_array[0] = gap;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*Set the position of all tracks from the start position, gaps and track sizes*/
|
||||
for(i = 0; i < track_num - 1; i++) {
|
||||
pos_array[i + 1] = pos_array[i] + size_array[i] + gap;
|
||||
}
|
||||
|
||||
lv_coord_t total_gird_size = pos_array[track_num - 1] + size_array[track_num - 1] - pos_array[0];
|
||||
|
||||
if(reverse) {
|
||||
for(i = 0; i < track_num; i++) {
|
||||
pos_array[i] = cont_size - pos_array[i] - size_array[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*Return the full size of the grid*/
|
||||
return total_gird_size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the grid of all children of an object. (Called recursively)
|
||||
* @param grid refresh objects only with this grid.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) {
|
||||
if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj);
|
||||
}
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
while(child) {
|
||||
report_grid_change_core(grid, child);
|
||||
child = lv_obj_get_child(obj, child);
|
||||
}
|
||||
|
||||
}
|
||||
143
src/lv_core/lv_grid.h
Normal file
143
src/lv_core/lv_grid.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* @file lv_grid.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GRID_H
|
||||
#define LV_GRID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**
|
||||
* Some helper defines
|
||||
* */
|
||||
#define _LV_GRID_CELL_SHIFT 4
|
||||
#define _LV_GRID_CELL_POS_MASK ((1 << _LV_GRID_CELL_SHIFT) - 1)
|
||||
#define _LV_GRID_CELL_SPAN_MASK (_LV_GRID_CELL_POS_MASK << _LV_GRID_CELL_SHIFT)
|
||||
#define _LV_GRID_CELL_FLAG_MASK (_LV_GRID_CELL_POS_MASK << (2 * _LV_GRID_CELL_SHIFT))
|
||||
#define _LV_GRID_CELL_PLACE(b) ((b) << (_LV_GRID_CELL_SHIFT * 2))
|
||||
|
||||
#define LV_GRID_START 0
|
||||
#define LV_GRID_CENTER 1
|
||||
#define LV_GRID_END 2
|
||||
#define LV_GRID_STRETCH 3
|
||||
#define LV_GRID_SPACE_EVENLY 4
|
||||
#define LV_GRID_SPACE_AROUND 5
|
||||
#define LV_GRID_SPACE_BETWEEN 6
|
||||
|
||||
#define LV_GRID_CELL_START(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_START)))
|
||||
#define LV_GRID_CELL_END(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_END)))
|
||||
#define LV_GRID_CELL_CENTER(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_CENTER)))
|
||||
#define LV_GRID_CELL_STRETCH(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_STRETCH)))
|
||||
|
||||
#define LV_GRID_GET_CELL_POS(c) ((c) & _LV_GRID_CELL_POS_MASK)
|
||||
#define LV_GRID_GET_CELL_SPAN(c) (((c) & _LV_GRID_CELL_SPAN_MASK) >> _LV_GRID_CELL_SHIFT)
|
||||
#define LV_GRID_GET_CELL_PLACE(c) ((c) >> (_LV_GRID_CELL_SHIFT * 2) & 0x7)
|
||||
|
||||
#define LV_GRID_FR(x) (_LV_COORD_GRID(x))
|
||||
#define LV_GRID_IS_FR(x) (LV_COORD_IS_GRID(x))
|
||||
#define LV_GRID_GET_FR(x) (LV_COORD_GET_GRID(x))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* Can't include lv_obj.h because it includes this header file */
|
||||
struct _lv_obj_t;
|
||||
typedef struct _lv_obj_t lv_obj_t;
|
||||
|
||||
typedef struct {
|
||||
const lv_coord_t * col_dsc;
|
||||
const lv_coord_t * row_dsc;
|
||||
uint8_t col_dsc_len;
|
||||
uint8_t row_dsc_len;
|
||||
lv_coord_t col_gap;
|
||||
lv_coord_t row_gap;
|
||||
uint8_t col_place;
|
||||
uint8_t row_place;
|
||||
}lv_grid_t;
|
||||
|
||||
typedef struct {
|
||||
lv_coord_t * x;
|
||||
lv_coord_t * y;
|
||||
lv_coord_t * w;
|
||||
lv_coord_t * h;
|
||||
uint32_t col_num;
|
||||
uint32_t row_num;
|
||||
lv_coord_t grid_w;
|
||||
lv_coord_t grid_h;
|
||||
}_lv_grid_calc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_grid_init(lv_grid_t * grid);
|
||||
|
||||
void lv_grid_set_template(lv_grid_t * grid, const lv_coord_t * col_dsc, uint8_t col_cnt, const lv_coord_t * row_dsc, uint8_t row_cnt);
|
||||
|
||||
void lv_grid_set_place(lv_grid_t * grid, uint8_t col_place, uint8_t row_place);
|
||||
|
||||
void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap);
|
||||
|
||||
/**
|
||||
* Set a grid for an object
|
||||
* @param obj pointer to an object
|
||||
* @param grid the grid to set
|
||||
*/
|
||||
void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid);
|
||||
|
||||
/**
|
||||
* Get the grid of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the grid, NULL if no grid
|
||||
*/
|
||||
const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj);
|
||||
|
||||
void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos);
|
||||
|
||||
/**
|
||||
* Notify all object if a style is modified
|
||||
* @param grid pointer to a grid. Only the objects with this grid will be notified
|
||||
* (NULL to notify all objects with any grid)
|
||||
*/
|
||||
void lv_obj_report_grid_change(const lv_grid_t * grid);
|
||||
|
||||
void _lv_grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
|
||||
|
||||
void _lv_grid_calc_free(_lv_grid_calc_t * calc);
|
||||
|
||||
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
|
||||
|
||||
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj);
|
||||
|
||||
|
||||
void _lv_grid_full_refresh(lv_obj_t * cont);
|
||||
|
||||
void lv_grid_item_refr_pos(lv_obj_t * item);
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GRID_H*/
|
||||
@@ -31,7 +31,6 @@
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *));
|
||||
static void lv_group_refocus(lv_group_t * g);
|
||||
static void obj_to_foreground(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -93,8 +92,8 @@ void lv_group_del(lv_group_t * group)
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
_LV_LL_READ(&group->obj_ll, obj) {
|
||||
if((*obj)->spec_attr) (*obj)->spec_attr->group_p = NULL;
|
||||
}
|
||||
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
@@ -112,7 +111,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
if(group == NULL) return;
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
_LV_LL_READ(group->obj_ll, obj_i) {
|
||||
_LV_LL_READ(&group->obj_ll, obj_i) {
|
||||
if((*obj_i) == obj) {
|
||||
LV_LOG_INFO("lv_group_add_obj: the object is already added to this group");
|
||||
return;
|
||||
@@ -120,15 +119,18 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
}
|
||||
|
||||
/*If the object is already in a group and focused then defocus it*/
|
||||
if(obj->group_p) {
|
||||
lv_group_t * group_cur = lv_obj_get_group(obj);
|
||||
if(group_cur) {
|
||||
if(lv_obj_is_focused(obj)) {
|
||||
lv_group_refocus(obj->group_p);
|
||||
lv_group_refocus(group_cur);
|
||||
|
||||
LV_LOG_INFO("lv_group_add_obj: assign object to an other group");
|
||||
}
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->group_p = group;
|
||||
|
||||
lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll);
|
||||
LV_ASSERT_MEM(next);
|
||||
if(next == NULL) return;
|
||||
@@ -147,7 +149,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
lv_group_t * g = lv_obj_get_group(obj);
|
||||
if(g == NULL) return;
|
||||
|
||||
/*Focus on the next object*/
|
||||
@@ -173,11 +175,11 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
||||
|
||||
/*Search the object and remove it from its group */
|
||||
lv_obj_t ** i;
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
_LV_LL_READ(&g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
_lv_ll_remove(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
obj->group_p = NULL;
|
||||
if(obj->spec_attr) obj->spec_attr->group_p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,8 +200,8 @@ void lv_group_remove_all_objs(lv_group_t * group)
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
_LV_LL_READ(group->obj_ll, obj) {
|
||||
(*obj)->group_p = NULL;
|
||||
_LV_LL_READ(&group->obj_ll, obj) {
|
||||
if((*obj)->spec_attr) (*obj)->spec_attr->group_p = NULL;
|
||||
}
|
||||
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
@@ -212,7 +214,7 @@ void lv_group_remove_all_objs(lv_group_t * group)
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
lv_group_t * g = obj->group_p;
|
||||
lv_group_t * g = lv_obj_get_group(obj);
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) return;
|
||||
@@ -223,7 +225,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
lv_group_set_editing(g, false);
|
||||
|
||||
lv_obj_t ** i;
|
||||
_LV_LL_READ(g->obj_ll, i) {
|
||||
_LV_LL_READ(&g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
@@ -240,9 +242,6 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -487,10 +486,10 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
||||
can_move = true;
|
||||
|
||||
if(obj_next == NULL) continue;
|
||||
if(lv_obj_get_state(*obj_next, LV_OBJ_PART_MAIN) & LV_STATE_DISABLED) continue;
|
||||
if(lv_obj_get_state(*obj_next) & LV_STATE_DISABLED) continue;
|
||||
|
||||
/*Hidden and disabled objects don't receive focus*/
|
||||
if(!lv_obj_get_hidden(*obj_next)) break;
|
||||
/*Hidden objects don't receive focus*/
|
||||
if(lv_obj_has_flag(*obj_next, LV_OBJ_FLAG_HIDDEN) == false) break;
|
||||
}
|
||||
|
||||
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
||||
@@ -508,28 +507,10 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foreground*/
|
||||
obj_to_foreground(*group->obj_focus);
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
if(group->focus_cb) group->focus_cb(group);
|
||||
}
|
||||
|
||||
static void obj_to_foreground(lv_obj_t * obj)
|
||||
{
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
i = lv_obj_get_parent(i);
|
||||
}
|
||||
|
||||
if(last_top != NULL) {
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_move_foreground(last_top);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
#include "lv_indev.h"
|
||||
#include "lv_disp.h"
|
||||
#include "lv_obj.h"
|
||||
#include "lv_indev_scroll.h"
|
||||
#include "lv_group.h"
|
||||
#include "lv_refr.h"
|
||||
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
@@ -40,9 +41,6 @@ static void indev_proc_press(lv_indev_proc_t * proc);
|
||||
static void indev_proc_release(lv_indev_proc_t * proc);
|
||||
static void indev_proc_reset_query_handler(lv_indev_t * indev);
|
||||
static void indev_click_focus(lv_indev_proc_t * proc);
|
||||
static void indev_drag(lv_indev_proc_t * proc);
|
||||
static void indev_drag_throw(lv_indev_proc_t * proc);
|
||||
static lv_obj_t * get_dragged_obj(lv_obj_t * obj);
|
||||
static void indev_gesture(lv_indev_proc_t * proc);
|
||||
static bool indev_reset_check(lv_indev_proc_t * proc);
|
||||
|
||||
@@ -213,7 +211,7 @@ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
|
||||
indev->cursor = cur_obj;
|
||||
lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp));
|
||||
lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x, indev->proc.types.pointer.act_point.y);
|
||||
lv_obj_set_click(indev->cursor, false);
|
||||
lv_obj_clear_flag(indev->cursor, LV_OBJ_FLAG_CLICKABLE);
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
@@ -289,20 +287,33 @@ uint32_t lv_indev_get_key(const lv_indev_t * indev)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and
|
||||
* Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return true: drag is in progress
|
||||
* @return LV_SCROLL_DIR_NONE: no scrolling now
|
||||
* LV_SCROLL_DIR_HOR/VER
|
||||
*/
|
||||
bool lv_indev_is_dragging(const lv_indev_t * indev)
|
||||
lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL) return false;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return false;
|
||||
return indev->proc.types.pointer.drag_in_prog == 0 ? false : true;
|
||||
return indev->proc.types.pointer.scroll_dir;
|
||||
}
|
||||
/**
|
||||
* Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return pointer to the currently scrolled object or NULL if no scrolling by this indev
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL) return NULL;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return NULL;
|
||||
return indev->proc.types.pointer.scroll_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the types.pointer.vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the types.pointer.vector
|
||||
@@ -325,36 +336,6 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually finish dragging.
|
||||
* `LV_SIGNAL_DRAG_END` and `LV_EVENT_DRAG_END` will be sent.
|
||||
* @param indev pointer to an input device
|
||||
* @return `LV_RES_INV` if the object being dragged was deleted. Else `LV_RES_OK`.
|
||||
*/
|
||||
lv_res_t lv_indev_finish_drag(lv_indev_t * indev)
|
||||
{
|
||||
if(indev == NULL) return LV_RES_OK;
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER) return LV_RES_OK;
|
||||
if(indev->proc.types.pointer.drag_in_prog == 0) return LV_RES_OK;
|
||||
|
||||
indev->proc.types.pointer.drag_in_prog = 0;
|
||||
indev->proc.types.pointer.drag_throw_vect.x = 0;
|
||||
indev->proc.types.pointer.drag_throw_vect.y = 0;
|
||||
|
||||
lv_obj_t * drag_obj;
|
||||
drag_obj = get_dragged_obj(indev->proc.types.pointer.act_obj);
|
||||
if(drag_obj == NULL) return LV_RES_OK;
|
||||
|
||||
lv_res_t res;
|
||||
res = drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
res = lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing until the next release
|
||||
* @param indev pointer to an input device
|
||||
@@ -847,9 +828,9 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
&proc->types.pointer.act_point);
|
||||
new_obj_searched = true;
|
||||
}
|
||||
/*If there is last object but it is not dragged and not protected also search*/
|
||||
else if(proc->types.pointer.drag_in_prog == 0 &&
|
||||
lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST) == false) {
|
||||
/*If there is last object but it is not scrolled and not protected also search*/
|
||||
else if(proc->types.pointer.scroll_obj == NULL &&
|
||||
lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_PRESS_LOCK) == false) {
|
||||
indev_obj_act = lv_indev_search_obj(lv_disp_get_layer_sys(disp), &proc->types.pointer.act_point);
|
||||
if(indev_obj_act == NULL) indev_obj_act = lv_indev_search_obj(lv_disp_get_layer_top(disp),
|
||||
&proc->types.pointer.act_point);
|
||||
@@ -857,19 +838,17 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
&proc->types.pointer.act_point);
|
||||
new_obj_searched = true;
|
||||
}
|
||||
/*If a draggable or a protected object was the last then keep it*/
|
||||
else {
|
||||
}
|
||||
|
||||
/*The last object might have drag throw. Stop it manually*/
|
||||
/*The last object might have scroll throw. Stop it manually*/
|
||||
if(new_obj_searched && proc->types.pointer.last_obj) {
|
||||
proc->types.pointer.drag_throw_vect.x = 0;
|
||||
proc->types.pointer.drag_throw_vect.y = 0;
|
||||
indev_drag_throw(proc);
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
_lv_scroll_throw_handler(proc);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
/*Do not use disabled objects*/
|
||||
if(indev_obj_act && (lv_obj_get_state(indev_obj_act, LV_OBJ_PART_MAIN) & LV_STATE_DISABLED)) {
|
||||
if(indev_obj_act && (lv_obj_get_state(indev_obj_act) & LV_STATE_DISABLED)) {
|
||||
indev_obj_act = proc->types.pointer.act_obj;
|
||||
}
|
||||
|
||||
@@ -883,11 +862,10 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
/*Save the obj because in special cases `act_obj` can change in the signal function*/
|
||||
lv_obj_t * last_obj = proc->types.pointer.act_obj;
|
||||
|
||||
last_obj->signal_cb(last_obj, LV_SIGNAL_PRESS_LOST, indev_act);
|
||||
lv_signal_send(last_obj, LV_SIGNAL_PRESS_LOST, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(last_obj, LV_EVENT_PRESS_LOST, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
}
|
||||
|
||||
proc->types.pointer.act_obj = indev_obj_act; /*Save the pressed object*/
|
||||
@@ -897,32 +875,17 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
/* Save the time when the obj pressed to count long press time.*/
|
||||
proc->pr_timestamp = lv_tick_get();
|
||||
proc->long_pr_sent = 0;
|
||||
proc->types.pointer.drag_limit_out = 0;
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.drag_sum.x = 0;
|
||||
proc->types.pointer.drag_sum.y = 0;
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
|
||||
proc->types.pointer.scroll_sum.x = 0;
|
||||
proc->types.pointer.scroll_sum.y = 0;
|
||||
proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE;
|
||||
proc->types.pointer.gesture_sent = 0;
|
||||
proc->types.pointer.gesture_sum.x = 0;
|
||||
proc->types.pointer.gesture_sum.y = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = indev_obj_act;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top) last_top = i;
|
||||
i = lv_obj_get_parent(i);
|
||||
}
|
||||
|
||||
if(last_top != NULL) {
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_move_foreground(last_top);
|
||||
}
|
||||
|
||||
/*Send a signal about the press*/
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, indev_act);
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_PRESSED, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
|
||||
@@ -937,43 +900,36 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
}
|
||||
}
|
||||
|
||||
/*Calculate the types.pointer.vector*/
|
||||
/*Calculate the vector and apply a low pass filter: new value = 0.5 * old_value + 0.5 * new_value*/
|
||||
proc->types.pointer.vect.x = proc->types.pointer.act_point.x - proc->types.pointer.last_point.x;
|
||||
proc->types.pointer.vect.y = proc->types.pointer.act_point.y - proc->types.pointer.last_point.y;
|
||||
|
||||
proc->types.pointer.drag_throw_vect.x = (proc->types.pointer.drag_throw_vect.x * 5) >> 3;
|
||||
proc->types.pointer.drag_throw_vect.y = (proc->types.pointer.drag_throw_vect.y * 5) >> 3;
|
||||
proc->types.pointer.scroll_throw_vect.x = (proc->types.pointer.scroll_throw_vect.x * 4) >> 3;
|
||||
proc->types.pointer.scroll_throw_vect.y = (proc->types.pointer.scroll_throw_vect.y * 4) >> 3;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.x < 0)
|
||||
proc->types.pointer.drag_throw_vect.x++;
|
||||
else if(proc->types.pointer.drag_throw_vect.x > 0)
|
||||
proc->types.pointer.drag_throw_vect.x--;
|
||||
proc->types.pointer.scroll_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3;
|
||||
proc->types.pointer.scroll_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.y < 0)
|
||||
proc->types.pointer.drag_throw_vect.y++;
|
||||
else if(proc->types.pointer.drag_throw_vect.y > 0)
|
||||
proc->types.pointer.drag_throw_vect.y--;
|
||||
proc->types.pointer.scroll_throw_vect_ori = proc->types.pointer.scroll_throw_vect;
|
||||
|
||||
proc->types.pointer.drag_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3;
|
||||
proc->types.pointer.drag_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3;
|
||||
|
||||
/*If there is active object and it can be dragged run the drag*/
|
||||
if(indev_obj_act != NULL) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSING, indev_act);
|
||||
if(indev_obj_act) {
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_PRESSING, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_PRESSING, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
if(indev_act->proc.wait_until_release) return;
|
||||
|
||||
indev_drag(proc);
|
||||
_lv_scroll_handler(proc);
|
||||
if(indev_reset_check(proc)) return;
|
||||
indev_gesture(proc);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
/*If there is no drag then check for long press time*/
|
||||
if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 0) {
|
||||
/*If there is no scrolling then check for long press time*/
|
||||
if(proc->types.pointer.scroll_obj == NULL && proc->long_pr_sent == 0) {
|
||||
/*Send a signal about the long press if enough time elapsed*/
|
||||
if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, indev_act);
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_LONG_PRESS, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
@@ -985,11 +941,12 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
proc->longpr_rep_timestamp = lv_tick_get();
|
||||
}
|
||||
}
|
||||
|
||||
/*Send long press repeated signal*/
|
||||
if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 1) {
|
||||
if(proc->types.pointer.scroll_obj == NULL && proc->long_pr_sent == 1) {
|
||||
/*Send a signal about the long press repeat if enough time elapsed*/
|
||||
if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, indev_act);
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
@@ -1013,73 +970,39 @@ static void indev_proc_release(lv_indev_proc_t * proc)
|
||||
proc->wait_until_release = 0;
|
||||
}
|
||||
indev_obj_act = proc->types.pointer.act_obj;
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
|
||||
/*Forget the act obj and send a released signal */
|
||||
if(indev_obj_act) {
|
||||
|
||||
/* If the object was protected against press lost then it possible that
|
||||
* the object is already not pressed but still it is the `act_obj`.
|
||||
* In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if
|
||||
* the indev is ON the `types.pointer.act_obj` */
|
||||
if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST)) {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
if(proc->types.pointer.drag_in_prog == 0) {
|
||||
if(proc->long_pr_sent == 0) {
|
||||
lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
/* The simple case: `act_obj` was not protected against press lost.
|
||||
* If it is already not pressed then `indev_proc_press` would set `indev_obj_act = NULL`*/
|
||||
else {
|
||||
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) {
|
||||
/*Send CLICK if no scrolling*/
|
||||
if(scroll_obj == NULL) {
|
||||
if(proc->long_pr_sent == 0) {
|
||||
lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
if(proc->types.pointer.drag_in_prog == 0) {
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
/*Send LV_EVENT_DRAG_THROW_BEGIN if required */
|
||||
/*If drag parent is active check recursively the drag_parent attribute*/
|
||||
lv_obj_t * drag_obj = get_dragged_obj(indev_obj_act);
|
||||
if(drag_obj) {
|
||||
if(lv_obj_get_drag_throw(drag_obj) && proc->types.pointer.drag_in_prog) {
|
||||
if(drag_obj->signal_cb) drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_THROW_BEGIN, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
/*Send RELEASE signal and event*/
|
||||
lv_signal_send(indev_obj_act, LV_SIGNAL_RELEASED, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
lv_event_send(drag_obj, LV_EVENT_DRAG_THROW_BEGIN, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
}
|
||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
proc->types.pointer.act_obj = NULL;
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
|
||||
}
|
||||
|
||||
/*The reset can be set in the signal function.
|
||||
* In case of reset query ignore the remaining parts.*/
|
||||
if(proc->types.pointer.last_obj != NULL && proc->reset_query == 0) {
|
||||
indev_drag_throw(proc);
|
||||
if(scroll_obj) {
|
||||
_lv_scroll_throw_handler(proc);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
}
|
||||
@@ -1096,16 +1019,15 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
|
||||
if(indev->proc.reset_query) {
|
||||
indev->proc.types.pointer.act_obj = NULL;
|
||||
indev->proc.types.pointer.last_obj = NULL;
|
||||
indev->proc.types.pointer.drag_limit_out = 0;
|
||||
indev->proc.types.pointer.drag_in_prog = 0;
|
||||
indev->proc.types.pointer.scroll_obj = NULL;
|
||||
indev->proc.long_pr_sent = 0;
|
||||
indev->proc.pr_timestamp = 0;
|
||||
indev->proc.longpr_rep_timestamp = 0;
|
||||
indev->proc.types.pointer.drag_sum.x = 0;
|
||||
indev->proc.types.pointer.drag_sum.y = 0;
|
||||
indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
|
||||
indev->proc.types.pointer.drag_throw_vect.x = 0;
|
||||
indev->proc.types.pointer.drag_throw_vect.y = 0;
|
||||
indev->proc.types.pointer.scroll_sum.x = 0;
|
||||
indev->proc.types.pointer.scroll_sum.y = 0;
|
||||
indev->proc.types.pointer.scroll_dir = LV_SCROLL_DIR_NONE;
|
||||
indev->proc.types.pointer.scroll_throw_vect.x = 0;
|
||||
indev->proc.types.pointer.scroll_throw_vect.y = 0;
|
||||
indev->proc.types.pointer.gesture_sum.x = 0;
|
||||
indev->proc.types.pointer.gesture_sum.y = 0;
|
||||
indev->proc.reset_query = 0;
|
||||
@@ -1123,10 +1045,11 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If the point is on this object check its children too*/
|
||||
if(lv_obj_hittest(obj, point)) {
|
||||
if(lv_obj_hit_test(obj, point)) {
|
||||
lv_obj_t * i;
|
||||
|
||||
_LV_LL_READ(obj->child_ll, i) {
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(obj);
|
||||
_LV_LL_READ(ll, i) {
|
||||
found_p = lv_indev_search_obj(i, point);
|
||||
|
||||
/*If a child was found then break*/
|
||||
@@ -1137,10 +1060,10 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
|
||||
/*If then the children was not ok, and this obj is clickable
|
||||
* and it or its parent is not hidden then save this object*/
|
||||
if(found_p == NULL && lv_obj_get_click(obj) != false) {
|
||||
if(found_p == NULL && lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE)) {
|
||||
lv_obj_t * hidden_i = obj;
|
||||
while(hidden_i != NULL) {
|
||||
if(lv_obj_get_hidden(hidden_i) == true) break;
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == true) break;
|
||||
hidden_i = lv_obj_get_parent(hidden_i);
|
||||
}
|
||||
/*No parent found with hidden == true*/
|
||||
@@ -1158,8 +1081,8 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
|
||||
static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
{
|
||||
/*Handle click focus*/
|
||||
lv_obj_t * obj_to_focus = lv_obj_get_focused_obj(indev_obj_act);
|
||||
if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_CLICK_FOCUS) == false &&
|
||||
lv_obj_t * obj_to_focus = _lv_obj_get_focused_obj(indev_obj_act);
|
||||
if(lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_CLICK_FOCUSABLE) &&
|
||||
proc->types.pointer.last_pressed != obj_to_focus) {
|
||||
#if LV_USE_GROUP
|
||||
lv_group_t * g_act = lv_obj_get_group(obj_to_focus);
|
||||
@@ -1246,256 +1169,21 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the dragging of indev_proc_p->types.pointer.act_obj
|
||||
* @param indev pointer to a input device state
|
||||
*/
|
||||
static void indev_drag(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_obj_t * drag_obj = get_dragged_obj(proc->types.pointer.act_obj);
|
||||
bool drag_just_started = false;
|
||||
|
||||
if(drag_obj == NULL) return;
|
||||
|
||||
if(lv_obj_get_drag(drag_obj) == false) return;
|
||||
|
||||
|
||||
lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);
|
||||
|
||||
/*Count the movement by drag*/
|
||||
if(proc->types.pointer.drag_limit_out == 0) {
|
||||
proc->types.pointer.drag_sum.x += proc->types.pointer.vect.x;
|
||||
proc->types.pointer.drag_sum.y += proc->types.pointer.vect.y;
|
||||
|
||||
/*Enough move?*/
|
||||
bool hor_en = false;
|
||||
bool ver_en = false;
|
||||
if(allowed_dirs == LV_DRAG_DIR_HOR || allowed_dirs == LV_DRAG_DIR_BOTH) {
|
||||
hor_en = true;
|
||||
}
|
||||
|
||||
if(allowed_dirs == LV_DRAG_DIR_VER || allowed_dirs == LV_DRAG_DIR_BOTH) {
|
||||
ver_en = true;
|
||||
}
|
||||
|
||||
if(allowed_dirs == LV_DRAG_DIR_ONE) {
|
||||
if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) {
|
||||
hor_en = true;
|
||||
}
|
||||
else {
|
||||
ver_en = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
|
||||
if((hor_en && LV_MATH_ABS(proc->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
|
||||
(ver_en && LV_MATH_ABS(proc->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {
|
||||
proc->types.pointer.drag_limit_out = 1;
|
||||
drag_just_started = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*If the drag limit is exceeded handle the dragging*/
|
||||
if(proc->types.pointer.drag_limit_out != 0) {
|
||||
/*Set new position if the vector is not zero*/
|
||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
||||
|
||||
lv_coord_t prev_x = drag_obj->coords.x1;
|
||||
lv_coord_t prev_y = drag_obj->coords.y1;
|
||||
lv_coord_t prev_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));
|
||||
lv_coord_t prev_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));
|
||||
|
||||
/*Get the coordinates of the object and modify them*/
|
||||
lv_coord_t act_x = lv_obj_get_x(drag_obj);
|
||||
lv_coord_t act_y = lv_obj_get_y(drag_obj);
|
||||
|
||||
if(allowed_dirs == LV_DRAG_DIR_BOTH) {
|
||||
if(drag_just_started) {
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
|
||||
act_x += proc->types.pointer.drag_sum.x;
|
||||
act_y += proc->types.pointer.drag_sum.y;
|
||||
}
|
||||
}
|
||||
else if(allowed_dirs == LV_DRAG_DIR_HOR) {
|
||||
if(drag_just_started) {
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
|
||||
proc->types.pointer.drag_sum.y = 0;
|
||||
act_x += proc->types.pointer.drag_sum.x;
|
||||
}
|
||||
}
|
||||
else if(allowed_dirs == LV_DRAG_DIR_VER) {
|
||||
if(drag_just_started) {
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
|
||||
proc->types.pointer.drag_sum.x = 0;
|
||||
act_y += proc->types.pointer.drag_sum.y;
|
||||
}
|
||||
}
|
||||
else if(allowed_dirs == LV_DRAG_DIR_ONE) {
|
||||
if(drag_just_started) {
|
||||
if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) {
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
|
||||
proc->types.pointer.drag_sum.y = 0;
|
||||
act_x += proc->types.pointer.drag_sum.x;
|
||||
}
|
||||
else {
|
||||
proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
|
||||
proc->types.pointer.drag_sum.x = 0;
|
||||
act_y += proc->types.pointer.drag_sum.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Move the object*/
|
||||
if(allowed_dirs == LV_DRAG_DIR_HOR ||
|
||||
allowed_dirs == LV_DRAG_DIR_BOTH ||
|
||||
(allowed_dirs == LV_DRAG_DIR_ONE &&
|
||||
LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y))) {
|
||||
act_x += proc->types.pointer.vect.x;
|
||||
}
|
||||
if(allowed_dirs == LV_DRAG_DIR_VER ||
|
||||
allowed_dirs == LV_DRAG_DIR_BOTH ||
|
||||
(allowed_dirs == LV_DRAG_DIR_ONE &&
|
||||
LV_MATH_ABS(proc->types.pointer.drag_sum.x) < LV_MATH_ABS(proc->types.pointer.drag_sum.y))) {
|
||||
act_y += proc->types.pointer.vect.y;
|
||||
}
|
||||
|
||||
uint16_t inv_buf_size =
|
||||
lv_disp_get_inv_buf_size(indev_act->driver.disp); /*Get the number of currently invalidated areas*/
|
||||
|
||||
lv_obj_set_pos(drag_obj, act_x, act_y);
|
||||
proc->types.pointer.drag_in_prog = 1;
|
||||
|
||||
/*If the object didn't moved then clear the invalidated areas*/
|
||||
if(drag_obj->coords.x1 == prev_x && drag_obj->coords.y1 == prev_y) {
|
||||
/*In a special case if the object is moved on a page and
|
||||
* the scrollable has fit == true and the object is dragged of the page then
|
||||
* while its coordinate is not changing only the parent's size is reduced */
|
||||
lv_coord_t act_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));
|
||||
lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));
|
||||
if(act_par_w == prev_par_w && act_par_h == prev_par_h) {
|
||||
uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp);
|
||||
_lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
/*Set the drag in progress flag*/
|
||||
/*Send the drag begin signal on first move*/
|
||||
if(drag_just_started) {
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle throwing by drag if the drag is ended
|
||||
* @param indev pointer to an input device state
|
||||
*/
|
||||
static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
{
|
||||
if(proc->types.pointer.drag_in_prog == 0) return;
|
||||
|
||||
lv_obj_t * drag_obj = get_dragged_obj(proc->types.pointer.last_obj);
|
||||
|
||||
if(drag_obj == NULL) return;
|
||||
|
||||
/*Return if the drag throw is not enabled*/
|
||||
if(lv_obj_get_drag_throw(drag_obj) == false) {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);
|
||||
|
||||
/*Reduce the vectors*/
|
||||
proc->types.pointer.drag_throw_vect.x =
|
||||
proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100;
|
||||
proc->types.pointer.drag_throw_vect.y =
|
||||
proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100;
|
||||
|
||||
if(proc->types.pointer.drag_throw_vect.x != 0 || proc->types.pointer.drag_throw_vect.y != 0) {
|
||||
/*Get the coordinates and modify them*/
|
||||
lv_area_t coords_ori;
|
||||
lv_obj_get_coords(drag_obj, &coords_ori);
|
||||
lv_coord_t act_x = lv_obj_get_x(drag_obj) + proc->types.pointer.drag_throw_vect.x;
|
||||
lv_coord_t act_y = lv_obj_get_y(drag_obj) + proc->types.pointer.drag_throw_vect.y;
|
||||
|
||||
if(allowed_dirs == LV_DRAG_DIR_BOTH) lv_obj_set_pos(drag_obj, act_x, act_y);
|
||||
else if(allowed_dirs == LV_DRAG_DIR_HOR) lv_obj_set_x(drag_obj, act_x);
|
||||
else if(allowed_dirs == LV_DRAG_DIR_VER) lv_obj_set_y(drag_obj, act_y);
|
||||
else if(allowed_dirs == LV_DRAG_DIR_ONE) {
|
||||
if(proc->types.pointer.drag_sum.x) lv_obj_set_x(drag_obj, act_x);
|
||||
else lv_obj_set_y(drag_obj, act_y);
|
||||
}
|
||||
lv_area_t coord_new;
|
||||
lv_obj_get_coords(drag_obj, &coord_new);
|
||||
|
||||
/*If non of the coordinates are changed then do not continue throwing*/
|
||||
if((coords_ori.x1 == coord_new.x1 || proc->types.pointer.drag_throw_vect.x == 0) &&
|
||||
(coords_ori.y1 == coord_new.y1 || proc->types.pointer.drag_throw_vect.y == 0)) {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
proc->types.pointer.vect.x = 0;
|
||||
proc->types.pointer.vect.y = 0;
|
||||
proc->types.pointer.drag_throw_vect.x = 0;
|
||||
proc->types.pointer.drag_throw_vect.y = 0;
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
|
||||
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
}
|
||||
/*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end
|
||||
signal*/
|
||||
else {
|
||||
proc->types.pointer.drag_in_prog = 0;
|
||||
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
|
||||
if(indev_reset_check(proc)) return;
|
||||
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the really dragged object by taking `drag_parent` into account.
|
||||
* @param obj the start object
|
||||
* @return the object to really drag
|
||||
*/
|
||||
static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return NULL;
|
||||
lv_obj_t * drag_obj = obj;
|
||||
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
|
||||
drag_obj = lv_obj_get_parent(drag_obj);
|
||||
}
|
||||
|
||||
return drag_obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle the gesture of indev_proc_p->types.pointer.act_obj
|
||||
* @param indev pointer to a input device state
|
||||
*/
|
||||
static void indev_gesture(lv_indev_proc_t * proc)
|
||||
void indev_gesture(lv_indev_proc_t * proc)
|
||||
{
|
||||
|
||||
if(proc->types.pointer.scroll_obj) return;
|
||||
if(proc->types.pointer.gesture_sent) return;
|
||||
|
||||
lv_obj_t * gesture_obj = proc->types.pointer.act_obj;
|
||||
|
||||
/*If gesture parent is active check recursively the gesture attribute*/
|
||||
while(gesture_obj && lv_obj_get_gesture_parent(gesture_obj)) {
|
||||
while(gesture_obj && lv_obj_has_flag(gesture_obj, LV_OBJ_FLAG_GESTURE_BUBBLE)) {
|
||||
gesture_obj = lv_obj_get_parent(gesture_obj);
|
||||
}
|
||||
|
||||
@@ -1538,6 +1226,7 @@ static void indev_gesture(lv_indev_proc_t * proc)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the reset_query flag has been set. If so, perform necessary global indev cleanup actions
|
||||
* @param proc pointer to an input device 'proc'
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -120,36 +120,36 @@ lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev);
|
||||
uint32_t lv_indev_get_key(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and
|
||||
* Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return true: drag is in progress
|
||||
* @return LV_SCROLL_DIR_NONE: no scrolling now
|
||||
* LV_SCROLL_DIR_HOR/VER
|
||||
*/
|
||||
bool lv_indev_is_dragging(const lv_indev_t * indev);
|
||||
lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the vector
|
||||
* @return pointer to the currently scrolled object or NULL if no scrolling by this indev
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the types.pointer.vector
|
||||
*/
|
||||
void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Manually finish dragging.
|
||||
* `LV_SIGNAL_DRAG_END` and `LV_EVENT_DRAG_END` will be sent.
|
||||
* @param indev pointer to an input device
|
||||
* @return `LV_RES_INV` if the object being dragged was deleted. Else `LV_RES_OK`.
|
||||
*/
|
||||
lv_res_t lv_indev_finish_drag(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Do nothing until the next release
|
||||
* @param indev pointer to an input device
|
||||
*/
|
||||
void lv_indev_wait_release(lv_indev_t * indev);
|
||||
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in indev proc functions.
|
||||
* NULL if no object is currently being handled or if groups aren't used.
|
||||
|
||||
561
src/lv_core/lv_indev_scroll.c
Normal file
561
src/lv_core/lv_indev_scroll.c
Normal file
@@ -0,0 +1,561 @@
|
||||
/**
|
||||
* @file lv_indev_scroll.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_indev.h"
|
||||
#include "lv_indev_scroll.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ELASTIC_SLOWNESS_FACTOR 4 /*Scrolling on elastic parts are slower by this factor*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc);
|
||||
static void init_scroll_limits(lv_indev_proc_t * proc);
|
||||
static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs);
|
||||
static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs);
|
||||
static void scroll_limit_diff(lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y);
|
||||
static lv_coord_t scroll_throw_predict_y(lv_indev_proc_t * proc);
|
||||
static lv_coord_t scroll_throw_predict_x(lv_indev_proc_t * proc);
|
||||
static lv_coord_t elastic_diff(lv_obj_t * obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Handle scrolling. Called by LVGL during input device processing
|
||||
* @param proc pointer to an input device's proc field
|
||||
*/
|
||||
void _lv_scroll_handler(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
/*If there is no scroll object yet try to find one*/
|
||||
if(scroll_obj == NULL) {
|
||||
proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x;
|
||||
proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y;
|
||||
|
||||
scroll_obj = find_scroll_obj(proc);
|
||||
if(scroll_obj == NULL) return;
|
||||
|
||||
init_scroll_limits(proc);
|
||||
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_BEGIN, indev_act);
|
||||
if(proc->reset_query) return;
|
||||
lv_event_send(scroll_obj, LV_EVENT_SCROLL_BEGIN, indev_act);
|
||||
if(proc->reset_query) return;
|
||||
}
|
||||
|
||||
/*Set new position or scroll if the vector is not zero*/
|
||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
||||
lv_coord_t diff_x = 0;
|
||||
lv_coord_t diff_y = 0;
|
||||
|
||||
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) {
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr);
|
||||
} else {
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb);
|
||||
}
|
||||
|
||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj);
|
||||
if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0;
|
||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0;
|
||||
|
||||
/*Respect the scroll limit area*/
|
||||
scroll_limit_diff(proc, &diff_x, &diff_y);
|
||||
|
||||
_lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y);
|
||||
proc->types.pointer.scroll_sum.x += diff_x;
|
||||
proc->types.pointer.scroll_sum.y += diff_y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle throwing after scrolling. Called by LVGL during input device processing
|
||||
* @param proc pointer to an input device's proc field
|
||||
*/
|
||||
void _lv_scroll_throw_handler(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
if(scroll_obj == NULL) return;
|
||||
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) return;
|
||||
|
||||
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_coord_t scroll_throw = indev_act->driver.scroll_throw;
|
||||
|
||||
if(lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_MOMENTUM) == false) {
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
}
|
||||
|
||||
lv_snap_align_t align_x = lv_obj_get_snap_align_x(scroll_obj);
|
||||
lv_snap_align_t align_y = lv_obj_get_snap_align_y(scroll_obj);
|
||||
|
||||
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_VER) {
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
/*If no snapping "throw"*/
|
||||
if(align_y == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
proc->types.pointer.scroll_throw_vect.y =
|
||||
proc->types.pointer.scroll_throw_vect.y * (100 - scroll_throw) / 100;
|
||||
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
|
||||
proc->types.pointer.scroll_throw_vect.y = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.y, st, sb);
|
||||
|
||||
_lv_obj_scroll_by_raw(scroll_obj, 0, proc->types.pointer.scroll_throw_vect.y);
|
||||
}
|
||||
/*With snapping find the nearest snap point and scroll there*/
|
||||
else {
|
||||
lv_coord_t diff_y = scroll_throw_predict_y(proc);
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
scroll_limit_diff(proc, NULL, &diff_y);
|
||||
lv_coord_t y = find_snap_point_y(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_y);
|
||||
lv_obj_scroll_by(scroll_obj, 0, diff_y + y, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) {
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
/*If no snapping "throw"*/
|
||||
if(align_x == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
proc->types.pointer.scroll_throw_vect.x =
|
||||
proc->types.pointer.scroll_throw_vect.x * (100 - scroll_throw) / 100;
|
||||
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
|
||||
proc->types.pointer.scroll_throw_vect.x = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.x, sl ,sr);
|
||||
|
||||
_lv_obj_scroll_by_raw(scroll_obj, proc->types.pointer.scroll_throw_vect.x, 0);
|
||||
}
|
||||
/*With snapping find the nearest snap point and scroll there*/
|
||||
else {
|
||||
lv_coord_t diff_x = scroll_throw_predict_x(proc);
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
scroll_limit_diff(proc, &diff_x, NULL);
|
||||
lv_coord_t x = find_snap_point_x(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_x);
|
||||
lv_obj_scroll_by(scroll_obj, x + diff_x, 0, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
/*Check if the scroll has finished */
|
||||
if(proc->types.pointer.scroll_throw_vect.x == 0 && proc->types.pointer.scroll_throw_vect.y == 0) {
|
||||
/*Revert if scrolled in*/
|
||||
/*If vertically scrollable and not controlled by snap*/
|
||||
if(align_y == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
if(st > 0 || sb > 0) {
|
||||
if(st < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, 0, st, LV_ANIM_ON);
|
||||
}
|
||||
else if(sb < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, 0, -sb, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*If horizontally scrollable and not controlled by snap*/
|
||||
if(align_x == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
if (sl > 0 || sr > 0) {
|
||||
if(sl < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, sl, 0, LV_ANIM_ON);
|
||||
}
|
||||
else if(sr < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, -sr, 0, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_END, indev_act);
|
||||
if(proc->reset_query) return;
|
||||
lv_event_send(scroll_obj, LV_EVENT_SCROLL_END, indev_act);
|
||||
if(proc->reset_query) return;
|
||||
|
||||
proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE;
|
||||
proc->types.pointer.scroll_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Predict where would a scroll throw end
|
||||
* @param indev pointer to an input device
|
||||
* @param dir `LV_DIR_VER` or `LV_DIR_HOR`
|
||||
* @return the difference compared to the current position when the throw would be finished
|
||||
*/
|
||||
lv_coord_t _lv_scroll_throw_predict(lv_indev_t * indev, lv_dir_t dir)
|
||||
{
|
||||
if(indev == NULL) return 0;
|
||||
lv_coord_t v;
|
||||
switch(dir) {
|
||||
case LV_DIR_VER:
|
||||
v = indev->proc.types.pointer.scroll_throw_vect_ori.y;
|
||||
break;
|
||||
case LV_DIR_HOR:
|
||||
v = indev->proc.types.pointer.scroll_throw_vect_ori.x;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv_coord_t scroll_throw = indev->driver.scroll_throw;
|
||||
lv_coord_t sum = 0;
|
||||
while(v) {
|
||||
sum += v;
|
||||
v = v * (100 - scroll_throw) / 100;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_obj_t * obj_candidate = NULL;
|
||||
lv_dir_t dir_candidate = LV_DIR_NONE;
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_coord_t scroll_limit = indev_act->driver.scroll_limit;
|
||||
|
||||
/* Go until find an scrollable object in the current direction
|
||||
* More precisely:
|
||||
* 1. Check the pressed object and all of its ancestors and try to find an object which is scrollable
|
||||
* 2. Scrollable means it has some content out of it's area
|
||||
* 3. If an object can be scrolled into the current direction then use it ("real match"")
|
||||
* 4. If can be scrolled on the current axis (hor/ver) save it as candidate (at least show an elastic scroll effect)
|
||||
* 5. Use the last candidate. Always the "deepest" parent or the object from point 3 */
|
||||
lv_obj_t * obj_act = proc->types.pointer.act_obj;
|
||||
while(obj_act) {
|
||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) {
|
||||
obj_act = lv_obj_get_parent(obj_act);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Decide if it's a horizontal or vertical scroll*/
|
||||
bool hor_en = false;
|
||||
bool ver_en = false;
|
||||
if(LV_MATH_ABS(proc->types.pointer.scroll_sum.x) > LV_MATH_ABS(proc->types.pointer.scroll_sum.y)) {
|
||||
hor_en = true;
|
||||
}
|
||||
else {
|
||||
ver_en = true;
|
||||
}
|
||||
|
||||
/*Consider both up-down or left/right scrollable according to the current direction*/
|
||||
bool up_en = ver_en;
|
||||
bool down_en = ver_en;
|
||||
bool left_en = hor_en;
|
||||
bool right_en = hor_en;
|
||||
|
||||
/*The object might have disabled some directions.*/
|
||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(obj_act);
|
||||
if((scroll_dir & LV_DIR_LEFT) == 0) left_en = false;
|
||||
if((scroll_dir & LV_DIR_RIGHT) == 0) right_en = false;
|
||||
if((scroll_dir & LV_DIR_TOP) == 0) up_en = false;
|
||||
if((scroll_dir & LV_DIR_BOTTOM) == 0) down_en = false;
|
||||
|
||||
/*The object is scrollable to a direction if its content overflow in that direction. */
|
||||
lv_coord_t st = lv_obj_get_scroll_top(obj_act);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj_act);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(obj_act);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(obj_act);
|
||||
|
||||
/* If this object is scrollable into the current scroll direction then save it as a candidate.
|
||||
* It's important only to be scrollable on the current axis (hor/ver) because if the scroll
|
||||
* is propagated to this object it can show at least elastic scroll effect.
|
||||
* But if not hor/ver scrollable do not scroll it at all (so it's not a good candidate) */
|
||||
if((st > 0 || sb > 0) &&
|
||||
((up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)))
|
||||
{
|
||||
obj_candidate = obj_act;
|
||||
dir_candidate = LV_SCROLL_DIR_VER;
|
||||
}
|
||||
|
||||
if((sl > 0 || sr > 0) &&
|
||||
((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit)))
|
||||
{
|
||||
obj_candidate = obj_act;
|
||||
dir_candidate = LV_SCROLL_DIR_HOR;
|
||||
}
|
||||
|
||||
if(st <= 0) up_en = false;
|
||||
if(sb <= 0) down_en = false;
|
||||
if(sl <= 0) left_en = false;
|
||||
if(sr <= 0) right_en = false;
|
||||
|
||||
/*If the object really can be scrolled into the current direction the use it. */
|
||||
if((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit) ||
|
||||
(up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit))
|
||||
{
|
||||
proc->types.pointer.scroll_dir = hor_en ? LV_SCROLL_DIR_HOR : LV_SCROLL_DIR_VER;
|
||||
break;
|
||||
}
|
||||
|
||||
/*Try the parent */
|
||||
obj_act = lv_obj_get_parent(obj_act);
|
||||
}
|
||||
|
||||
/*Use the last candidate*/
|
||||
if(obj_candidate) {
|
||||
proc->types.pointer.scroll_dir = dir_candidate;
|
||||
proc->types.pointer.scroll_obj = obj_candidate;
|
||||
proc->types.pointer.scroll_sum.x = 0;
|
||||
proc->types.pointer.scroll_sum.y = 0;
|
||||
}
|
||||
|
||||
return obj_candidate;
|
||||
}
|
||||
|
||||
static void init_scroll_limits(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_obj_t * obj = proc->types.pointer.scroll_obj;
|
||||
/*If there no STOP allow scrolling anywhere*/
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_STOP) == false) {
|
||||
lv_area_set(&proc->types.pointer.scroll_area, LV_COORD_MIN, LV_COORD_MIN, LV_COORD_MAX, LV_COORD_MAX);
|
||||
}
|
||||
/*With STOP limit the scrolling to the perv and next snap point*/
|
||||
else {
|
||||
switch(lv_obj_get_snap_align_y(obj)) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y1 + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y1 - 1, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y2, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y2, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER: {
|
||||
lv_coord_t y_mid = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2;
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, y_mid + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, y_mid - 1, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
proc->types.pointer.scroll_area.y1 = LV_COORD_MIN;
|
||||
proc->types.pointer.scroll_area.y2 = LV_COORD_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(lv_obj_get_snap_align_x(obj)) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x1, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x2, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x2, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER: {
|
||||
lv_coord_t x_mid = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2;
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, x_mid + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, x_mid - 1, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
proc->types.pointer.scroll_area.x1 = LV_COORD_MIN;
|
||||
proc->types.pointer.scroll_area.x2 = LV_COORD_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Allow scrolling on the edges. It will be reverted to the edge due to snapping anyway*/
|
||||
if(proc->types.pointer.scroll_area.x1 == 0) proc->types.pointer.scroll_area.x1 = LV_COORD_MIN;
|
||||
if(proc->types.pointer.scroll_area.x2 == 0) proc->types.pointer.scroll_area.x2 = LV_COORD_MAX;
|
||||
if(proc->types.pointer.scroll_area.y1 == 0) proc->types.pointer.scroll_area.y1 = LV_COORD_MIN;
|
||||
if(proc->types.pointer.scroll_area.y2 == 0) proc->types.pointer.scroll_area.y2 = LV_COORD_MAX;
|
||||
}
|
||||
|
||||
static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
||||
{
|
||||
lv_snap_align_t align = lv_obj_get_snap_align_x(obj);
|
||||
if(align == LV_SCROLL_SNAP_ALIGN_NONE) return 0;
|
||||
|
||||
lv_coord_t dist = LV_COORD_MAX;
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child_back(obj, NULL);
|
||||
while(child) {
|
||||
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) {
|
||||
lv_coord_t x_child = 0;
|
||||
lv_coord_t x_parent = 0;
|
||||
switch(align) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
x_child = child->coords.x1;
|
||||
x_parent = obj->coords.x1;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
x_child = child->coords.x2;
|
||||
x_parent = obj->coords.x2;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER:
|
||||
x_child = child->coords.x1 + lv_area_get_width(&child->coords) / 2;
|
||||
x_parent = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2;
|
||||
}
|
||||
|
||||
x_child += ofs;
|
||||
if(x_child >= min && x_child <= max) {
|
||||
lv_coord_t x = x_child - x_parent;
|
||||
if(LV_MATH_ABS(x) < LV_MATH_ABS(dist)) dist = x;
|
||||
}
|
||||
}
|
||||
|
||||
child = lv_obj_get_child_back(obj, child);
|
||||
}
|
||||
|
||||
return dist == LV_COORD_MAX ? 0: -dist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for snap point in the `min` - `max` range.
|
||||
* @param obj the object on which snap point should be found
|
||||
* @param min ignore snap points smaller then this. (Absolute coordinate)
|
||||
* @param max ignore snap points greater then this. (Absolute coordinate)
|
||||
* @param ofs offset to snap points. Useful the get a snap point in an imagined case
|
||||
* what if children are already moved by this value
|
||||
* @return the distance of the snap point.
|
||||
*/
|
||||
static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
||||
{
|
||||
lv_snap_align_t align = lv_obj_get_snap_align_y(obj);
|
||||
if(align == LV_SCROLL_SNAP_ALIGN_NONE) return 0;
|
||||
|
||||
lv_coord_t dist = LV_COORD_MAX;
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child_back(obj, NULL);
|
||||
while(child) {
|
||||
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) {
|
||||
lv_coord_t y_child = 0;
|
||||
lv_coord_t y_parent = 0;
|
||||
switch(align) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
y_child = child->coords.y1;
|
||||
y_parent = obj->coords.y1;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
y_child = child->coords.y2;
|
||||
y_parent = obj->coords.y2;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER:
|
||||
y_child = child->coords.y1 + lv_area_get_height(&child->coords) / 2;
|
||||
y_parent = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2;
|
||||
}
|
||||
|
||||
y_child += ofs;
|
||||
if(y_child >= min && y_child <= max) {
|
||||
lv_coord_t y = y_child - y_parent;
|
||||
if(LV_MATH_ABS(y) < LV_MATH_ABS(dist)) dist = y;
|
||||
}
|
||||
}
|
||||
|
||||
child = lv_obj_get_child_back(obj, child);
|
||||
}
|
||||
|
||||
return dist == LV_COORD_MAX ? 0 : -dist;
|
||||
}
|
||||
|
||||
static void scroll_limit_diff(lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y)
|
||||
{
|
||||
if(diff_y) {
|
||||
if(proc->types.pointer.scroll_sum.y + *diff_y < proc->types.pointer.scroll_area.y1) {
|
||||
*diff_y = proc->types.pointer.scroll_area.y1 - proc->types.pointer.scroll_sum.y;
|
||||
}
|
||||
|
||||
if(proc->types.pointer.scroll_sum.y + *diff_y > proc->types.pointer.scroll_area.y2) {
|
||||
*diff_y = proc->types.pointer.scroll_area.y2 - proc->types.pointer.scroll_sum.y;
|
||||
}
|
||||
}
|
||||
|
||||
if(diff_x) {
|
||||
if(proc->types.pointer.scroll_sum.x + *diff_x < proc->types.pointer.scroll_area.x1) {
|
||||
*diff_x = proc->types.pointer.scroll_area.x1 - proc->types.pointer.scroll_sum.x;
|
||||
}
|
||||
|
||||
if(proc->types.pointer.scroll_sum.x + *diff_x > proc->types.pointer.scroll_area.x2) {
|
||||
*diff_x = proc->types.pointer.scroll_area.x2 - proc->types.pointer.scroll_sum.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static lv_coord_t scroll_throw_predict_y(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_coord_t y = proc->types.pointer.scroll_throw_vect.y;
|
||||
lv_coord_t move = 0;
|
||||
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_coord_t scroll_throw = indev_act->driver.scroll_throw;
|
||||
|
||||
while(y) {
|
||||
move += y;
|
||||
y = y * (100 - scroll_throw) / 100;
|
||||
}
|
||||
return move;
|
||||
}
|
||||
|
||||
|
||||
static lv_coord_t scroll_throw_predict_x(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_coord_t x = proc->types.pointer.scroll_throw_vect.x;
|
||||
lv_coord_t move = 0;
|
||||
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_coord_t scroll_throw = indev_act->driver.scroll_throw;
|
||||
|
||||
while(x) {
|
||||
move += x;
|
||||
x = x * (100 - scroll_throw) / 100;
|
||||
}
|
||||
return move;
|
||||
}
|
||||
|
||||
static lv_coord_t elastic_diff(lv_obj_t * obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end)
|
||||
{
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ELASTIC)) {
|
||||
/*Elastic scroll if scrolled in*/
|
||||
if(scroll_end < 0) diff = (diff + ELASTIC_SLOWNESS_FACTOR / 2) / ELASTIC_SLOWNESS_FACTOR;
|
||||
else if(scroll_start < 0) diff = (diff + ELASTIC_SLOWNESS_FACTOR / 2) / ELASTIC_SLOWNESS_FACTOR;
|
||||
} else {
|
||||
/*Scroll back to the boundary id required*/
|
||||
if(scroll_end + diff < 0) diff = - scroll_end;
|
||||
if(scroll_start - diff < 0) diff = scroll_start;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
59
src/lv_core/lv_indev_scroll.h
Normal file
59
src/lv_core/lv_indev_scroll.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @file lv_indev_scroll.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_INDEV_SCROLL_H
|
||||
#define LV_INDEV_SCROLL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Handle scrolling. Called by LVGL during input device processing
|
||||
* @param proc pointer to an input device's proc field
|
||||
*/
|
||||
void _lv_scroll_handler(lv_indev_proc_t * proc);
|
||||
|
||||
|
||||
/**
|
||||
* Handle throwing after scrolling. Called by LVGL during input device processing
|
||||
* @param proc pointer to an input device's proc field
|
||||
*/
|
||||
void _lv_scroll_throw_handler(lv_indev_proc_t * proc);
|
||||
|
||||
/**
|
||||
* Predict where would a scroll throw end
|
||||
* @param indev pointer to an input device
|
||||
* @param dir `LV_DIR_VER` or `LV_DIR_HOR`
|
||||
* @return the difference compared to the current position when the throw would be finished
|
||||
*/
|
||||
lv_coord_t _lv_scroll_throw_predict(lv_indev_t * indev, lv_dir_t dir);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_INDEV_SCROLL_H*/
|
||||
3777
src/lv_core/lv_obj.c
3777
src/lv_core/lv_obj.c
File diff suppressed because it is too large
Load Diff
1012
src/lv_core/lv_obj.h
1012
src/lv_core/lv_obj.h
File diff suppressed because it is too large
Load Diff
594
src/lv_core/lv_obj_draw.c
Normal file
594
src/lv_core/lv_obj_draw.c
Normal file
@@ -0,0 +1,594 @@
|
||||
/**
|
||||
* @file lv_obj_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_draw.h"
|
||||
#include "lv_obj.h"
|
||||
#include "lv_disp.h"
|
||||
#include "lv_indev.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_obj"
|
||||
|
||||
#define SCROLLBAR_MIN_SIZE (LV_DPX(10))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a rectangle draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_REL` or `LV_SLIDER_PART_KNOB`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If an `*_opa` filed is set to `LV_OPA_TRANSP` the related properties won't be initialized.
|
||||
* Should be initialized with `lv_draw_rect_dsc_init(draw_dsc)`.
|
||||
* @note Only the relevant fields will be set.
|
||||
* E.g. if `border width == 0` the other border properties won't be evaluated.
|
||||
*/
|
||||
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->radius = lv_obj_get_style_radius(obj, part);
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
|
||||
if(opa_scale <= LV_OPA_MIN) {
|
||||
draw_dsc->bg_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->border_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->shadow_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->pattern_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->value_opa = LV_OPA_TRANSP;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
|
||||
if(draw_dsc->bg_opa > LV_OPA_MIN) {
|
||||
draw_dsc->bg_color = lv_obj_get_style_bg_color(obj, part);
|
||||
draw_dsc->bg_grad_dir = lv_obj_get_style_bg_grad_dir(obj, part);
|
||||
if(draw_dsc->bg_grad_dir != LV_GRAD_DIR_NONE) {
|
||||
draw_dsc->bg_grad_color = lv_obj_get_style_bg_grad_color(obj, part);
|
||||
draw_dsc->bg_main_color_stop = lv_obj_get_style_bg_main_stop(obj, part);
|
||||
draw_dsc->bg_grad_color_stop = lv_obj_get_style_bg_grad_stop(obj, part);
|
||||
}
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->bg_blend_mode = lv_obj_get_style_bg_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
|
||||
if(draw_dsc->border_width) {
|
||||
if(draw_dsc->border_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
|
||||
if(draw_dsc->border_opa > LV_OPA_MIN) {
|
||||
draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
|
||||
draw_dsc->border_color = lv_obj_get_style_border_color(obj, part);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->border_blend_mode = lv_obj_get_style_border_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_OUTLINE
|
||||
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
|
||||
if(draw_dsc->outline_width) {
|
||||
if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
||||
if(draw_dsc->outline_opa > LV_OPA_MIN) {
|
||||
draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
||||
draw_dsc->outline_color = lv_obj_get_style_outline_color(obj, part);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->outline_blend_mode = lv_obj_get_style_outline_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_PATTERN
|
||||
draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part);
|
||||
if(draw_dsc->pattern_image) {
|
||||
if(draw_dsc->pattern_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->pattern_opa = lv_obj_get_style_pattern_opa(obj, part);
|
||||
if(draw_dsc->pattern_opa > LV_OPA_MIN) {
|
||||
draw_dsc->pattern_recolor_opa = lv_obj_get_style_pattern_recolor_opa(obj, part);
|
||||
draw_dsc->pattern_repeat = lv_obj_get_style_pattern_repeat(obj, part);
|
||||
if(lv_img_src_get_type(draw_dsc->pattern_image) == LV_IMG_SRC_SYMBOL) {
|
||||
draw_dsc->pattern_recolor = lv_obj_get_style_pattern_recolor(obj, part);
|
||||
draw_dsc->pattern_font = lv_obj_get_style_text_font(obj, part);
|
||||
}
|
||||
else if(draw_dsc->pattern_recolor_opa > LV_OPA_MIN) {
|
||||
draw_dsc->pattern_recolor = lv_obj_get_style_pattern_recolor(obj, part);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->pattern_blend_mode = lv_obj_get_style_pattern_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_SHADOW
|
||||
draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
|
||||
if(draw_dsc->shadow_width) {
|
||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
||||
draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part);
|
||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
||||
draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
|
||||
draw_dsc->shadow_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
|
||||
draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part);
|
||||
draw_dsc->shadow_color = lv_obj_get_style_shadow_color(obj, part);
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->shadow_blend_mode = lv_obj_get_style_shadow_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_VALUE_STR
|
||||
draw_dsc->value_str = lv_obj_get_style_value_str(obj, part);
|
||||
if(draw_dsc->value_str) {
|
||||
if(draw_dsc->value_opa > LV_OPA_MIN) {
|
||||
draw_dsc->value_opa = lv_obj_get_style_value_opa(obj, part);
|
||||
if(draw_dsc->value_opa > LV_OPA_MIN) {
|
||||
draw_dsc->value_ofs_x = lv_obj_get_style_value_ofs_x(obj, part);
|
||||
draw_dsc->value_ofs_y = lv_obj_get_style_value_ofs_y(obj, part);
|
||||
draw_dsc->value_color = lv_obj_get_style_value_color(obj, part);
|
||||
draw_dsc->value_font = lv_obj_get_style_value_font(obj, part);
|
||||
draw_dsc->value_letter_space = lv_obj_get_style_value_letter_space(obj, part);
|
||||
draw_dsc->value_line_space = lv_obj_get_style_value_line_space(obj, part);
|
||||
draw_dsc->value_align = lv_obj_get_style_value_align(obj, part);
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->value_blend_mode = lv_obj_get_style_value_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
if(opa_scale < LV_OPA_MAX) {
|
||||
draw_dsc->bg_opa = (uint16_t)((uint16_t)draw_dsc->bg_opa * opa_scale) >> 8;
|
||||
draw_dsc->border_opa = (uint16_t)((uint16_t)draw_dsc->border_opa * opa_scale) >> 8;
|
||||
draw_dsc->shadow_opa = (uint16_t)((uint16_t)draw_dsc->shadow_opa * opa_scale) >> 8;
|
||||
draw_dsc->pattern_opa = (uint16_t)((uint16_t)draw_dsc->pattern_opa * opa_scale) >> 8;
|
||||
draw_dsc->value_opa = (uint16_t)((uint16_t)draw_dsc->value_opa * opa_scale) >> 8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a label draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_REL` or `LV_SLIDER_PART_KNOB`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t part, lv_draw_label_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->opa = lv_obj_get_style_text_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
|
||||
if(opa_scale < LV_OPA_MAX) {
|
||||
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
#endif
|
||||
|
||||
draw_dsc->color = lv_obj_get_style_text_color(obj, part);
|
||||
draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part);
|
||||
draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part);
|
||||
draw_dsc->decor = lv_obj_get_style_text_decor(obj, part);
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->blend_mode = lv_obj_get_style_text_blend_mode(obj, part);
|
||||
#endif
|
||||
|
||||
draw_dsc->font = lv_obj_get_style_text_font(obj, part);
|
||||
|
||||
if(draw_dsc->sel_start != LV_DRAW_LABEL_NO_TXT_SEL && draw_dsc->sel_end != LV_DRAW_LABEL_NO_TXT_SEL) {
|
||||
draw_dsc->color = lv_obj_get_style_text_sel_color(obj, part);
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
draw_dsc->bidi_dir = lv_obj_get_base_dir(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an image draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_IMG_PART_MAIN`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->opa = lv_obj_get_style_image_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
|
||||
if(opa_scale < LV_OPA_MAX) {
|
||||
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
#endif
|
||||
|
||||
draw_dsc->angle = 0;
|
||||
draw_dsc->zoom = LV_IMG_ZOOM_NONE;
|
||||
draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
|
||||
draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
|
||||
|
||||
draw_dsc->recolor_opa = lv_obj_get_style_image_recolor_opa(obj, part);
|
||||
if(draw_dsc->recolor_opa > 0) {
|
||||
draw_dsc->recolor = lv_obj_get_style_image_recolor(obj, part);
|
||||
}
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->blend_mode = lv_obj_get_style_image_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a line draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_LINE_PART_MAIN`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->width = lv_obj_get_style_line_width(obj, part);
|
||||
if(draw_dsc->width == 0) return;
|
||||
|
||||
draw_dsc->opa = lv_obj_get_style_line_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
#if LV_USE_OPA_SCALE
|
||||
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
|
||||
if(opa_scale < LV_OPA_MAX) {
|
||||
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
#endif
|
||||
|
||||
draw_dsc->color = lv_obj_get_style_line_color(obj, part);
|
||||
|
||||
draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part);
|
||||
if(draw_dsc->dash_width) {
|
||||
draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part);
|
||||
}
|
||||
|
||||
draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part);
|
||||
draw_dsc->round_end = draw_dsc->round_start;
|
||||
|
||||
#if LV_USE_BLEND_MODES
|
||||
draw_dsc->blend_mode = lv_obj_get_style_line_blend_mode(obj, part);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object
|
||||
* @return the extra size required around the object
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part)
|
||||
{
|
||||
lv_coord_t s = 0;
|
||||
|
||||
lv_coord_t sh_width = lv_obj_get_style_shadow_width(obj, part);
|
||||
if(sh_width) {
|
||||
lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part);
|
||||
if(sh_opa > LV_OPA_MIN) {
|
||||
sh_width = sh_width / 2; /*THe blur adds only half width*/
|
||||
sh_width++;
|
||||
sh_width += lv_obj_get_style_shadow_spread(obj, part);
|
||||
lv_style_int_t sh_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
|
||||
lv_style_int_t sh_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
|
||||
sh_width += LV_MATH_MAX(LV_MATH_ABS(sh_ofs_x), LV_MATH_ABS(sh_ofs_y));
|
||||
s = LV_MATH_MAX(s, sh_width);
|
||||
}
|
||||
}
|
||||
|
||||
const char * value_str = lv_obj_get_style_value_str(obj, part);
|
||||
if(value_str) {
|
||||
lv_opa_t value_opa = lv_obj_get_style_value_opa(obj, part);
|
||||
if(value_opa > LV_OPA_MIN) {
|
||||
lv_style_int_t letter_space = lv_obj_get_style_value_letter_space(obj, part);
|
||||
lv_style_int_t line_space = lv_obj_get_style_value_letter_space(obj, part);
|
||||
const lv_font_t * font = lv_obj_get_style_value_font(obj, part);
|
||||
|
||||
lv_point_t txt_size;
|
||||
_lv_txt_get_size(&txt_size, value_str, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
|
||||
lv_area_t value_area;
|
||||
value_area.x1 = 0;
|
||||
value_area.y1 = 0;
|
||||
value_area.x2 = txt_size.x - 1;
|
||||
value_area.y2 = txt_size.y - 1;
|
||||
|
||||
lv_style_int_t align = lv_obj_get_style_value_align(obj, part);
|
||||
lv_style_int_t xofs = lv_obj_get_style_value_ofs_x(obj, part);
|
||||
lv_style_int_t yofs = lv_obj_get_style_value_ofs_y(obj, part);
|
||||
lv_point_t p_align;
|
||||
_lv_area_align(&obj->coords, &value_area, align, &p_align);
|
||||
|
||||
value_area.x1 += p_align.x + xofs;
|
||||
value_area.y1 += p_align.y + yofs;
|
||||
value_area.x2 += p_align.x + xofs;
|
||||
value_area.y2 += p_align.y + yofs;
|
||||
|
||||
s = LV_MATH_MAX(s, obj->coords.x1 - value_area.x1);
|
||||
s = LV_MATH_MAX(s, obj->coords.y1 - value_area.y1);
|
||||
s = LV_MATH_MAX(s, value_area.x2 - obj->coords.x2);
|
||||
s = LV_MATH_MAX(s, value_area.y2 - obj->coords.y2);
|
||||
}
|
||||
}
|
||||
|
||||
lv_style_int_t outline_width = lv_obj_get_style_outline_width(obj, part);
|
||||
if(outline_width) {
|
||||
lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
||||
if(outline_opa > LV_OPA_MIN) {
|
||||
lv_style_int_t outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
||||
s = LV_MATH_MAX(s, outline_pad + outline_width);
|
||||
}
|
||||
}
|
||||
|
||||
lv_coord_t w = lv_obj_get_style_transform_width(obj, part);
|
||||
lv_coord_t h = lv_obj_get_style_transform_height(obj, part);
|
||||
lv_coord_t wh = LV_MATH_MAX(w, h);
|
||||
if(wh > 0) s += wh;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object to refresh the extended draw area.
|
||||
* The result will be written into `obj->ext_draw_pad`
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void _lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_coord_t s = 0;
|
||||
obj->signal_cb(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, &s);
|
||||
|
||||
/*Store the result if the special attrs already allocated*/
|
||||
if(obj->spec_attr) {
|
||||
obj->spec_attr->ext_draw_pad = s;
|
||||
}
|
||||
/* Allocate spec. attrs. only if the result is not zero.
|
||||
* Zero is the default value if the spec. attr. are not defined. */
|
||||
else if(s != 0) {
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->ext_draw_pad = s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw scrollbars on an object is required
|
||||
* @param obj pointer to an object
|
||||
* @param clip_area the clip area coming from the design function
|
||||
*/
|
||||
void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area)
|
||||
{
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) == false) return;
|
||||
|
||||
lv_scroll_dir_t sm = lv_obj_get_scroll_mode(obj);
|
||||
if(sm == LV_SCROLL_MODE_OFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*If there is no indev scrolling this object but the moe is active return*/
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
if(sm == LV_SCROLL_MODE_ACTIVE) {
|
||||
bool found = false;
|
||||
while(indev) {
|
||||
if(lv_indev_get_scroll_obj(indev) == obj) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
if(!found) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lv_coord_t st = lv_obj_get_scroll_top(obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
||||
|
||||
/*Return if too small content to scroll*/
|
||||
if(sm == LV_SCROLL_MODE_AUTO && st <= 0 && sb <= 0 && sl <= 0 && sr <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_coord_t end_space = lv_obj_get_style_scrollbar_space_end(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t side_space = lv_obj_get_style_scrollbar_space_side(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t tickness = lv_obj_get_style_scrollbar_tickness(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_coord_t obj_h = lv_obj_get_height(obj);
|
||||
lv_coord_t obj_w = lv_obj_get_width(obj);
|
||||
|
||||
lv_scroll_dir_t dir = lv_obj_get_scroll_dir(obj);
|
||||
|
||||
bool ver_draw = false;
|
||||
if((dir & LV_DIR_VER) &&
|
||||
((sm == LV_SCROLL_MODE_ON) ||
|
||||
(sm == LV_SCROLL_MODE_AUTO && (st > 0 || sb > 0)) ||
|
||||
(sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_VER))) {
|
||||
ver_draw = true;
|
||||
}
|
||||
|
||||
|
||||
bool hor_draw = false;
|
||||
if((dir & LV_DIR_HOR) &&
|
||||
((sm == LV_SCROLL_MODE_ON) ||
|
||||
(sm == LV_SCROLL_MODE_AUTO && (sl > 0 || sr > 0)) ||
|
||||
(sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_HOR))) {
|
||||
hor_draw = true;
|
||||
}
|
||||
|
||||
|
||||
lv_coord_t ver_reg_space = ver_draw ? tickness + side_space : 0;
|
||||
lv_coord_t hor_req_space = hor_draw ? tickness + side_space : 0;
|
||||
lv_coord_t rem;
|
||||
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_res_t sb_res = scrollbar_init_draw_dsc(obj, &draw_dsc);
|
||||
if(sb_res != LV_RES_OK) return;
|
||||
|
||||
lv_area_t area;
|
||||
area.y1 = obj->coords.y1;
|
||||
area.y2 = obj->coords.y2;
|
||||
area.x2 = obj->coords.x2 - side_space;
|
||||
area.x1 = area.x2 - tickness;
|
||||
|
||||
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
|
||||
if(ver_draw && _lv_area_is_on(&area, clip_area)) {
|
||||
lv_coord_t content_h = obj_h + st + sb;
|
||||
lv_coord_t sb_h = ((obj_h - end_space * 2 - hor_req_space) * obj_h) / content_h;
|
||||
sb_h = LV_MATH_MAX(sb_h, SCROLLBAR_MIN_SIZE);
|
||||
rem = (obj_h - end_space * 2 - hor_req_space) - sb_h; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
||||
lv_coord_t scroll_h = content_h - obj_h; /*The size of the content which can be really scrolled*/
|
||||
if(scroll_h <= 0) {
|
||||
area.y1 = obj->coords.y1 + end_space;
|
||||
area.y2 = obj->coords.y2 - end_space - hor_req_space - 1;
|
||||
area.x2 = obj->coords.x2 - side_space;
|
||||
area.x1 = area.x2 - tickness + 1;
|
||||
} else {
|
||||
lv_coord_t sb_y = (rem * sb) / scroll_h;
|
||||
sb_y = rem - sb_y;
|
||||
|
||||
area.y1 = obj->coords.y1 + sb_y + end_space;
|
||||
area.y2 = area.y1 + sb_h - 1;
|
||||
area.x2 = obj->coords.x2 - side_space;
|
||||
area.x1 = area.x2 - tickness;
|
||||
if(area.y1 < obj->coords.y1 + end_space) {
|
||||
area.y1 = obj->coords.y1 + end_space;
|
||||
if(area.y1 + SCROLLBAR_MIN_SIZE > area.y2) area.y2 = area.y1 + SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
if(area.y2 > obj->coords.y2 - hor_req_space - end_space) {
|
||||
area.y2 = obj->coords.y2 - hor_req_space - end_space;
|
||||
if(area.y2 - SCROLLBAR_MIN_SIZE < area.y1) area.y1 = area.y2 - SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
lv_draw_rect(&area, clip_area, &draw_dsc);
|
||||
}
|
||||
|
||||
area.y2 = obj->coords.y2 - side_space;
|
||||
area.y1 =area.y2 - tickness;
|
||||
area.x1 = obj->coords.x1;
|
||||
area.x2 = obj->coords.x2;
|
||||
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
|
||||
if(hor_draw && _lv_area_is_on(&area, clip_area)) {
|
||||
lv_coord_t content_w = obj_w + sl + sr;
|
||||
lv_coord_t sb_w = ((obj_w - end_space * 2 - ver_reg_space) * obj_w) / content_w;
|
||||
sb_w = LV_MATH_MAX(sb_w, SCROLLBAR_MIN_SIZE);
|
||||
rem = (obj_w - end_space * 2 - ver_reg_space) - sb_w; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
||||
lv_coord_t scroll_w = content_w - obj_w; /*The size of the content which can be really scrolled*/
|
||||
if(scroll_w <= 0) {
|
||||
area.y2 = obj->coords.y2 - side_space;
|
||||
area.y1 = area.y2 - tickness + 1;
|
||||
area.x1 = obj->coords.x1 + end_space;
|
||||
area.x2 = obj->coords.x2 - end_space - ver_reg_space - 1;
|
||||
} else {
|
||||
lv_coord_t sb_x = (rem * sr) / scroll_w;
|
||||
sb_x = rem - sb_x;
|
||||
|
||||
area.x1 = obj->coords.x1 + sb_x + end_space;
|
||||
area.x2 = area.x1 + sb_w - 1;
|
||||
area.y2 = obj->coords.y2 - side_space;
|
||||
area.y1 = area.y2 - tickness;
|
||||
if(area.x1 < obj->coords.x1 + end_space) {
|
||||
area.x1 = obj->coords.x1 + end_space;
|
||||
if(area.x1 + SCROLLBAR_MIN_SIZE > area.x2) area.x2 = area.x1 + SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
if(area.x2 > obj->coords.x2 - ver_reg_space - end_space) {
|
||||
area.x2 = obj->coords.x2 - ver_reg_space - end_space;
|
||||
if(area.x2 - SCROLLBAR_MIN_SIZE < area.x1) area.x1 = area.x2 - SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
lv_draw_rect(&area, clip_area, &draw_dsc);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the draw descriptor for the scrollbar
|
||||
* @param obj pointer to an object
|
||||
* @param dsc the draw descriptor to initialize
|
||||
* @return LV_RES_OK: the scrollbar is visible; LV_RES_INV: the scrollbar is not visible
|
||||
*/
|
||||
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc)
|
||||
{
|
||||
lv_draw_rect_dsc_init(dsc);
|
||||
dsc->bg_opa = lv_obj_get_style_scrollbar_bg_opa(obj, LV_OBJ_PART_MAIN);
|
||||
if(dsc->bg_opa > LV_OPA_MIN) {
|
||||
dsc->bg_color = lv_obj_get_style_scrollbar_bg_color(obj, LV_OBJ_PART_MAIN);
|
||||
}
|
||||
|
||||
dsc->border_opa = lv_obj_get_style_scrollbar_border_opa(obj, LV_OBJ_PART_MAIN);
|
||||
if(dsc->border_opa > LV_OPA_MIN) {
|
||||
dsc->border_width = lv_obj_get_style_scrollbar_border_width(obj, LV_OBJ_PART_MAIN);
|
||||
if(dsc->border_width > 0) {
|
||||
dsc->border_color = lv_obj_get_style_scrollbar_border_color(obj, LV_OBJ_PART_MAIN);
|
||||
} else {
|
||||
dsc->border_opa = LV_OPA_TRANSP;
|
||||
}
|
||||
}
|
||||
|
||||
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN);
|
||||
if(opa_scale < LV_OPA_MAX) {
|
||||
dsc->bg_opa = (dsc->bg_opa * opa_scale) >> 8;
|
||||
dsc->border_opa = (dsc->bg_opa * opa_scale) >> 8;
|
||||
}
|
||||
|
||||
if(dsc->bg_opa != LV_OPA_TRANSP || dsc->border_opa != LV_OPA_TRANSP) {
|
||||
dsc->radius = lv_obj_get_style_scrollbar_radius(obj, LV_OBJ_PART_MAIN);
|
||||
return LV_RES_OK;
|
||||
} else {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
106
src/lv_core/lv_obj_draw.h
Normal file
106
src/lv_core/lv_obj_draw.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file lv_obj_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_DRAW_H
|
||||
#define LV_OBJ_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a rectangle draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_REL` or `LV_SLIDER_PART_KNOB`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If an `*_opa` filed is set to `LV_OPA_TRANSP` the related properties won't be initialized.
|
||||
* Should be initialized with `lv_draw_rect_dsc_init(draw_dsc)`.
|
||||
* @note Only the relevant fields will be set.
|
||||
* E.g. if `border width == 0` the other border properties won't be evaluated.
|
||||
*/
|
||||
void lv_obj_init_draw_rect_dsc(struct _lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize a label draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_REL` or `LV_SLIDER_PART_KNOB`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_label_dsc(struct _lv_obj_t * obj, uint8_t part, lv_draw_label_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize an image draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_IMG_PART_MAIN`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_img_dsc(struct _lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize a line draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param type type of style. E.g. `LV_LINE_PART_MAIN`
|
||||
* @param draw_dsc the descriptor the initialize.
|
||||
* If the `opa` filed is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_line_dsc(struct _lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object
|
||||
* @return the extra size required around the object
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_draw_rect_ext_pad_size(struct _lv_obj_t * obj, uint8_t part);
|
||||
|
||||
/**
|
||||
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object to refresh the extended draw area.
|
||||
* The result will be written into `obj->ext_draw_pad`
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void _lv_obj_refresh_ext_draw_pad(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Draw scrollbars on an object is required
|
||||
* @param obj pointer to an object
|
||||
* @param clip_area the clip area coming from the design function
|
||||
*/
|
||||
void _lv_obj_draw_scrollbar(struct _lv_obj_t * obj, const lv_area_t * clip_area);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_DRAW_H*/
|
||||
781
src/lv_core/lv_obj_pos.c
Normal file
781
src/lv_core/lv_obj_pos.c
Normal file
@@ -0,0 +1,781 @@
|
||||
/**
|
||||
* @file lv_obj_pos.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_obj"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set relative the position of an object (relative to the parent)
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side of the parent plus the parent's left padding or a grid cell
|
||||
* @param y new distance from the top side of the parent plus the parent's right padding or a grid cell
|
||||
* @note Zero value value means place the object is on the left padding of the parent, and not on the left edge.
|
||||
* @note A grid cell can be and explicit placement with cell position and span:
|
||||
* `LV_GRID_CELL_START/END/CENTER/STRETCH(pos, span)`
|
||||
* or "auto" to place the object on the grid in the creation order of other children
|
||||
* `LV_GRID_AUTO_START/END/CENTER/STRETCH`
|
||||
* @note to use grid placement the parent needs have a defined grid with `lv_obj_set_grid`
|
||||
*/
|
||||
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
obj->x_set = x;
|
||||
obj->y_set = y;
|
||||
|
||||
bool gi = _lv_obj_is_grid_item(obj);
|
||||
bool fi = _lv_obj_is_flex_item(obj);
|
||||
|
||||
/*For consistency set the size to stretched if the objects is stretched on the grid*/
|
||||
if(gi) {
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->x_set) == LV_GRID_STRETCH) obj->w_set = LV_SIZE_STRETCH;
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->y_set) == LV_GRID_STRETCH) obj->h_set = LV_SIZE_STRETCH;
|
||||
}
|
||||
|
||||
/*If not grid or flex item but has grid or flex position set the position to 0*/
|
||||
if(!gi) {
|
||||
if(LV_COORD_IS_GRID(x)) x = 0;
|
||||
if(LV_COORD_IS_GRID(y)) y = 0;
|
||||
}
|
||||
|
||||
if(!fi) {
|
||||
if(LV_COORD_IS_FLEX(x)) x = 0;
|
||||
if(LV_COORD_IS_FLEX(y)) y = 0;
|
||||
}
|
||||
|
||||
/*If the object is on a grid item let the grid to position it. */
|
||||
if(gi) {
|
||||
lv_grid_item_refr_pos(obj);
|
||||
} else if(fi) {
|
||||
_lv_flex_refresh(lv_obj_get_parent(obj));
|
||||
} else {
|
||||
_lv_obj_move_to(obj, x, y, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the x coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side from the parent plus the parent's left padding or a grid cell
|
||||
*/
|
||||
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_set_pos(obj, x, obj->y_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the y coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param y new distance from the top of the parent plus the parent's top padding or a grid cell
|
||||
*/
|
||||
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_set_pos(obj, obj->x_set, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
* @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
bool gi = _lv_obj_is_grid_item(obj);
|
||||
bool fi = _lv_obj_is_flex_item(obj);
|
||||
bool x_stretch = false;
|
||||
bool y_stretch = false;
|
||||
|
||||
/*Use `LV_SIZE_STRETCH` value if the layout changes the size of the object*/
|
||||
if(gi) {
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->x_set)) x_stretch = true;
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->y_set)) y_stretch = true;
|
||||
}
|
||||
if(fi) {
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_ROW && LV_COORD_GET_FLEX(obj->y_set) == LV_FLEX_PLACE_STRETCH) y_stretch = true;
|
||||
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_COLUMN && LV_COORD_GET_FLEX(obj->x_set) == LV_FLEX_PLACE_STRETCH) x_stretch = true;
|
||||
}
|
||||
|
||||
if(x_stretch) w = LV_SIZE_STRETCH;
|
||||
if(y_stretch) h = LV_SIZE_STRETCH;
|
||||
|
||||
obj->w_set = w;
|
||||
obj->h_set = h;
|
||||
|
||||
/*If both stretched the size is managed by the grid*/
|
||||
if(x_stretch && y_stretch) return;
|
||||
|
||||
if(x_stretch) w = lv_obj_get_width(obj);
|
||||
if(y_stretch) h = lv_obj_get_height(obj);
|
||||
|
||||
/*Calculate the required auto sizes*/
|
||||
bool x_auto = obj->w_set == LV_SIZE_AUTO ? true : false;
|
||||
bool y_auto = obj->h_set == LV_SIZE_AUTO ? true : false;
|
||||
|
||||
/*Be sure the object is not scrolled when it has auto size*/
|
||||
if(x_auto) lv_obj_scroll_to_x(obj, 0, LV_ANIM_OFF);
|
||||
if(y_auto) lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF);
|
||||
|
||||
if(x_auto && y_auto) _lv_obj_calc_auto_size(obj, &w, &h);
|
||||
else if(x_auto) _lv_obj_calc_auto_size(obj, &w, NULL);
|
||||
else if(y_auto) _lv_obj_calc_auto_size(obj, NULL, &h);
|
||||
|
||||
/*Calculate the required auto sizes*/
|
||||
bool pct_w = LV_COORD_IS_PCT(obj->w_set) ? true : false;
|
||||
bool pct_h = LV_COORD_IS_PCT(obj->h_set) ? true : false;
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(parent);
|
||||
lv_coord_t cont_h = lv_obj_get_height_fit(parent);
|
||||
if(pct_w) w = (_LV_COORD_GET_PCT(obj->w_set) * cont_w) / 100;
|
||||
if(pct_h) h = (_LV_COORD_GET_PCT(obj->h_set) * cont_h) / 100;
|
||||
}
|
||||
|
||||
refr_size(obj, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_set_size(obj, w, obj->h_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_set_size(obj, obj->w_set, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width reduced by the left and right padding.
|
||||
* @param obj pointer to an object
|
||||
* @param w the width without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_width(lv_obj_t * obj, lv_coord_t w)
|
||||
{
|
||||
lv_style_int_t pleft = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t pright = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_set_width(obj, w + pleft + pright);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height reduced by the top and bottom padding.
|
||||
* @param obj pointer to an object
|
||||
* @param h the height without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_height(lv_obj_t * obj, lv_coord_t h)
|
||||
{
|
||||
lv_style_int_t ptop = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t pbottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_set_height(obj, h + ptop + pbottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width of an object by taking the left and right margin into account.
|
||||
* The object width will be `obj_w = w - margin_left - margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @param w new height including margins in pixels
|
||||
*/
|
||||
void lv_obj_set_width_margin(lv_obj_t * obj, lv_coord_t w)
|
||||
{
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_set_width(obj, w - mleft - mright);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height of an object by taking the top and bottom margin into account.
|
||||
* The object height will be `obj_h = h - margin_top - margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @param h new height including margins in pixels
|
||||
*/
|
||||
void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h)
|
||||
{
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_set_height(obj, h - mtop - mbottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
if(base == NULL) base = lv_obj_get_parent(obj);
|
||||
|
||||
LV_ASSERT_OBJ(base, LV_OBJX_NAME);
|
||||
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
switch(align) {
|
||||
case LV_ALIGN_CENTER:
|
||||
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
case LV_ALIGN_IN_TOP_LEFT:
|
||||
x = 0;
|
||||
y = 0;
|
||||
break;
|
||||
case LV_ALIGN_IN_TOP_MID:
|
||||
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_IN_TOP_RIGHT:
|
||||
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_IN_BOTTOM_LEFT:
|
||||
x = 0;
|
||||
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
case LV_ALIGN_IN_BOTTOM_MID:
|
||||
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_IN_BOTTOM_RIGHT:
|
||||
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_IN_LEFT_MID:
|
||||
x = 0;
|
||||
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_IN_RIGHT_MID:
|
||||
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_TOP_LEFT:
|
||||
x = 0;
|
||||
y = -lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_TOP_MID:
|
||||
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
y = -lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_TOP_RIGHT:
|
||||
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
y = -lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_BOTTOM_LEFT:
|
||||
x = 0;
|
||||
y = lv_obj_get_height(base);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_BOTTOM_MID:
|
||||
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
|
||||
y = lv_obj_get_height(base);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_BOTTOM_RIGHT:
|
||||
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
|
||||
y = lv_obj_get_height(base);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_TOP:
|
||||
x = -lv_obj_get_width(obj);
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_MID:
|
||||
x = -lv_obj_get_width(obj);
|
||||
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_LEFT_BOTTOM:
|
||||
x = -lv_obj_get_width(obj);
|
||||
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_RIGHT_TOP:
|
||||
x = lv_obj_get_width(base);
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_RIGHT_MID:
|
||||
x = lv_obj_get_width(base);
|
||||
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
|
||||
break;
|
||||
|
||||
case LV_ALIGN_OUT_RIGHT_BOTTOM:
|
||||
x = lv_obj_get_width(base);
|
||||
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
x += x_ofs + base->coords.x1 - parent->coords.x1 - lv_obj_get_style_pad_left(parent, LV_OBJ_PART_MAIN);
|
||||
y += y_ofs + base->coords.y1 - parent->coords.y1 - lv_obj_get_style_pad_top(parent, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_set_pos(obj, x, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the coordinates of an object to an area
|
||||
* @param obj pointer to an object
|
||||
* @param coords_out pointer to an area to store the coordinates
|
||||
*/
|
||||
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords_out)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_area_copy(coords_out, &obj->coords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.
|
||||
* (Without the size of the border or other extra graphical elements)
|
||||
* @param coords_out store the result area here
|
||||
*/
|
||||
void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_out)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_border_side_t part = lv_obj_get_style_border_side(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t w = lv_obj_get_style_border_width(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
if(part & LV_BORDER_SIDE_LEFT) coords_out->x1 += w;
|
||||
if(part & LV_BORDER_SIDE_RIGHT) coords_out->x2 -= w;
|
||||
if(part & LV_BORDER_SIDE_TOP) coords_out->y1 += w;
|
||||
if(part & LV_BORDER_SIDE_BOTTOM) coords_out->y2 -= w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the x coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the left side of its parent plus the parent's left padding
|
||||
* @note Zero return value means the object is on the left padding of the parent, and not on the left edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_x(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_coord_t rel_x;
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
rel_x = obj->coords.x1 - parent->coords.x1;
|
||||
rel_x += lv_obj_get_scroll_x(parent);
|
||||
rel_x -= lv_obj_get_style_pad_left(parent, LV_OBJ_PART_MAIN);
|
||||
}
|
||||
else {
|
||||
rel_x = obj->coords.x1;
|
||||
}
|
||||
return rel_x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the y coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the top side of its parent plus the parent's top padding
|
||||
* @note Zero return value means the object is on the top padding of the parent, and not on the top edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_y(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_coord_t rel_y;
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
rel_y = obj->coords.y1 - parent->coords.y1;
|
||||
rel_y += lv_obj_get_scroll_y(parent);
|
||||
rel_y -= lv_obj_get_style_pad_top(parent, LV_OBJ_PART_MAIN);
|
||||
}
|
||||
else {
|
||||
rel_y = obj->coords.y1;
|
||||
}
|
||||
return rel_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the width in pixels
|
||||
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
return lv_area_get_width(&obj->coords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the height in pixels
|
||||
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
return lv_area_get_height(&obj->coords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get that width reduced by the left and right padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the width which still fits into the container without causing overflow
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_fit(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
return lv_obj_get_width(obj) - left - right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get that height reduced by the top an bottom padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the height which still fits into the container without causing overflow
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top((lv_obj_t *)obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t bottom = lv_obj_get_style_pad_bottom((lv_obj_t *)obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
return lv_obj_get_height(obj) - top - bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of an object by taking the top and bottom margin into account.
|
||||
* The returned height will be `obj_h + margin_top + margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_margin(const lv_obj_t * obj)
|
||||
{
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
return lv_obj_get_height(obj) + mtop + mbottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of an object by taking the left and right margin into account.
|
||||
* The returned width will be `obj_w + margin_left + margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_margin(const lv_obj_t * obj)
|
||||
{
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
return lv_obj_get_width(obj) + mleft + mright;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_width(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_point_t p = {0, LV_COORD_MIN};
|
||||
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
|
||||
return p.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_height(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_point_t p = {LV_COORD_MIN, 0};
|
||||
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
|
||||
return p.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle if the size of the internal (virtual) content of an object has changed.
|
||||
* @param obj pointer to an object
|
||||
* @return false: nothing happened; true: refresh happened
|
||||
*/
|
||||
bool _lv_obj_handle_self_size_chg(struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->w_set != LV_SIZE_AUTO && obj->h_set == LV_SIZE_AUTO) return false;
|
||||
|
||||
lv_obj_set_size(obj, obj->w_set, obj->h_set);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the "auto size". It's `auto_size = max(children_size, self_size)`
|
||||
* @param obj pointer to an object
|
||||
* @param w_out store the width here. NULL to not calculate width
|
||||
* @param h_out store the height here. NULL to not calculate height
|
||||
*/
|
||||
void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out)
|
||||
{
|
||||
if(!w_out && !h_out) return;
|
||||
/*Get the bounding box of the children*/
|
||||
if(w_out) {
|
||||
lv_coord_t scroll_right = lv_obj_get_scroll_right(obj);
|
||||
lv_coord_t scroll_left = lv_obj_get_scroll_left(obj);
|
||||
*w_out = lv_obj_get_width(obj) + scroll_right + scroll_left;
|
||||
}
|
||||
|
||||
if(h_out) {
|
||||
lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(obj);
|
||||
lv_coord_t scroll_top = lv_obj_get_scroll_top(obj);
|
||||
*h_out = lv_obj_get_height(obj) + scroll_bottom + scroll_top;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an object to a given x and y coordinate.
|
||||
* It's the core function to move objects but user should use `lv_obj_set_pos/x/y/..` etc.
|
||||
* @param obj pointer to an object to move
|
||||
* @param x the new x coordinate in pixels
|
||||
* @param y the new y coordinate in pixels
|
||||
* @param notify_parent true: send `LV_SIGNAL_CHILD_CHG` to the parent if `obj` moved; false: do not notify the parent
|
||||
*/
|
||||
void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_parent)
|
||||
{
|
||||
/*Convert x and y to absolute coordinates*/
|
||||
lv_obj_t * parent = obj->parent;
|
||||
|
||||
if(parent) {
|
||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(parent, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(parent, LV_OBJ_PART_MAIN);
|
||||
|
||||
x += pad_left + parent->coords.x1 - lv_obj_get_scroll_x(parent);
|
||||
y += pad_top + parent->coords.y1 - lv_obj_get_scroll_y(parent);
|
||||
} else {
|
||||
/*If no parent then it's screen but screen can't be on a grid*/
|
||||
if(LV_COORD_IS_GRID(obj->x_set) || LV_COORD_IS_GRID(obj->x_set)) {
|
||||
obj->x_set = 0;
|
||||
obj->y_set = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*Calculate and set the movement*/
|
||||
lv_point_t diff;
|
||||
diff.x = x - obj->coords.x1;
|
||||
diff.y = y - obj->coords.y1;
|
||||
|
||||
/* Do nothing if the position is not changed */
|
||||
/* It is very important else recursive positioning can
|
||||
* occur without position change*/
|
||||
if(diff.x == 0 && diff.y == 0) return;
|
||||
|
||||
/*Invalidate the original area*/
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
/*Save the original coordinates*/
|
||||
lv_area_t ori;
|
||||
lv_obj_get_coords(obj, &ori);
|
||||
|
||||
obj->coords.x1 += diff.x;
|
||||
obj->coords.y1 += diff.y;
|
||||
obj->coords.x2 += diff.x;
|
||||
obj->coords.y2 += diff.y;
|
||||
|
||||
_lv_obj_move_children_by(obj, diff.x, diff.y);
|
||||
|
||||
/*Inform the object about its new coordinates*/
|
||||
obj->signal_cb(obj, LV_SIGNAL_COORD_CHG, &ori);
|
||||
|
||||
/*Send a signal to the parent too*/
|
||||
if(parent && notify_parent) parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj);
|
||||
|
||||
/*Invalidate the new area*/
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reposition the children of an object. (Called recursively)
|
||||
* @param obj pointer to an object which children will be repositioned
|
||||
* @param x_diff x coordinate shift
|
||||
* @param y_diff y coordinate shift
|
||||
*/
|
||||
void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff)
|
||||
{
|
||||
lv_obj_t * i;
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(obj);
|
||||
_LV_LL_READ(ll, i) {
|
||||
i->coords.x1 += x_diff;
|
||||
i->coords.y1 += y_diff;
|
||||
i->coords.x2 += x_diff;
|
||||
i->coords.y2 += y_diff;
|
||||
|
||||
_lv_obj_move_children_by(i, x_diff, y_diff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an object is valid grid item or not.
|
||||
* @param obj pointer to an object to check
|
||||
* @return true: grid item; false: not grid item
|
||||
*/
|
||||
bool _lv_obj_is_grid_item(lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * cont = lv_obj_get_parent(obj);
|
||||
if(cont == NULL) return false;
|
||||
const lv_grid_t * g = lv_obj_get_grid(cont);
|
||||
if(g == NULL) return false;
|
||||
if(g->col_dsc == NULL) return false;
|
||||
if(g->row_dsc == NULL) return false;
|
||||
if(g->row_dsc_len == 0) return false;
|
||||
if(g->col_dsc_len == 0) return false;
|
||||
if(LV_COORD_IS_GRID(obj->x_set) == false || LV_COORD_IS_GRID(obj->y_set) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an object is valid grid item or not.
|
||||
* @param obj pointer to an object to check
|
||||
* @return true: grid item; false: not grid item
|
||||
*/
|
||||
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * cont = lv_obj_get_parent(obj);
|
||||
if(cont == NULL) return false;
|
||||
if(lv_obj_get_flex_dir(cont) == LV_FLEX_DIR_NONE) return false;
|
||||
if(LV_COORD_IS_FLEX(obj->x_set) == false || LV_COORD_IS_FLEX(obj->y_set) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set the size of an object.
|
||||
* It's the core function to set the size of objects but user should use `lv_obj_set_size/width/height/..` etc.
|
||||
* @param obj pointer to an object
|
||||
* @param w the new width in pixels
|
||||
* @param h the new height in pixels
|
||||
* @return true: the size was changed; false: `w` and `h` was equal to the current width and height so nothing happened.
|
||||
*/
|
||||
static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
{
|
||||
/* Do nothing if the size is not changed */
|
||||
/* It is very important else recursive resizing can
|
||||
* occur without size change*/
|
||||
if(lv_obj_get_width(obj) == w && lv_obj_get_height(obj) == h) {
|
||||
return false;
|
||||
}
|
||||
/*Invalidate the original area*/
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
/*Save the original coordinates*/
|
||||
lv_area_t ori;
|
||||
lv_obj_get_coords(obj, &ori);
|
||||
|
||||
/* Grow size is managed by the flexbox in `LV_SIGNAL_CHILD_CHG`
|
||||
* So the real current value now.
|
||||
* w or h has `LV_FLEX_GROW(x)` value which is a very large special value
|
||||
* so it should be avoided to use such a special value as width*/
|
||||
if(_LV_FLEX_GET_GROW(obj->w_set)) w = lv_obj_get_width(obj);
|
||||
if(_LV_FLEX_GET_GROW(obj->h_set)) h = lv_obj_get_height(obj);
|
||||
|
||||
/* Set the length and height
|
||||
* Be sure the content is not scrolled in an invalid position on the new size*/
|
||||
obj->coords.y2 = obj->coords.y1 + h - 1;
|
||||
if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL) {
|
||||
obj->coords.x1 = obj->coords.x2 - w + 1;
|
||||
}
|
||||
else {
|
||||
obj->coords.x2 = obj->coords.x1 + w - 1;
|
||||
}
|
||||
|
||||
/*Send a signal to the object with its new coordinates*/
|
||||
obj->signal_cb(obj, LV_SIGNAL_COORD_CHG, &ori);
|
||||
|
||||
/*Send a signal to the parent too*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
if(par != NULL) par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);
|
||||
|
||||
/*Invalidate the new area*/
|
||||
lv_obj_invalidate(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
265
src/lv_core/lv_obj_pos.h
Normal file
265
src/lv_core/lv_obj_pos.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file lv_obj_pos.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_POS_H
|
||||
#define LV_OBJ_POS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct _lv_obj_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set relative the position of an object (relative to the parent)
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side of the parent plus the parent's left padding or a grid cell
|
||||
* @param y new distance from the top side of the parent plus the parent's right padding or a grid cell
|
||||
* @note Zero value value means place the object on the left/top padding of the parent, and not on the left/top edge.
|
||||
* @note For grid cells: `LV_GRID_CELL_START/END/CENTER/STRETCH(pos, span)`
|
||||
* For flex items: `LV_FLEX_POS/START/END/CENTER`
|
||||
* For percentage size: `LV_SIZE_PCT(pct)`
|
||||
* For auto size (to set size to children size): `LV_SIZE_AUTO`
|
||||
* @note to use grid placement the parent needs have a defined grid with `lv_obj_set_grid`
|
||||
*/
|
||||
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the x coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side from the parent plus the parent's left padding or a grid cell
|
||||
*/
|
||||
void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x);
|
||||
|
||||
/**
|
||||
* Set the y coordinate of a object
|
||||
* @param obj pointer to an object
|
||||
* @param y new distance from the top of the parent plus the parent's top padding or a grid cell
|
||||
*/
|
||||
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the size of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
* @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
|
||||
*/
|
||||
void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the width reduced by the left and right padding.
|
||||
* @param obj pointer to an object
|
||||
* @param w the width without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_width(struct _lv_obj_t * obj, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height reduced by the top and bottom padding.
|
||||
* @param obj pointer to an object
|
||||
* @param h the height without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_height(struct _lv_obj_t * obj, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Set the width of an object by taking the left and right margin into account.
|
||||
* The object width will be `obj_w = w - margin_left - margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @param w new height including margins in pixels
|
||||
*/
|
||||
void lv_obj_set_width_margin(struct _lv_obj_t * obj, lv_coord_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an object by taking the top and bottom margin into account.
|
||||
* The object height will be `obj_h = h - margin_top - margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @param h new height including margins in pixels
|
||||
*/
|
||||
void lv_obj_set_height_margin(struct _lv_obj_t * obj, lv_coord_t h);
|
||||
|
||||
/**
|
||||
* Align an object to an other object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align(struct _lv_obj_t * obj, const struct _lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
|
||||
|
||||
/**
|
||||
* Copy the coordinates of an object to an area
|
||||
* @param obj pointer to an object
|
||||
* @param coords_out pointer to an area to store the coordinates
|
||||
*/
|
||||
void lv_obj_get_coords(const struct _lv_obj_t * obj, lv_area_t * coords_out);
|
||||
|
||||
/**
|
||||
* Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.
|
||||
* (Without the size of the border or other extra graphical elements)
|
||||
* @param coords_out store the result area here
|
||||
*/
|
||||
void lv_obj_get_inner_coords(const struct _lv_obj_t * obj, lv_area_t * coords_out);
|
||||
|
||||
/**
|
||||
* Get the x coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the left side of its parent plus the parent's left padding
|
||||
* @note Zero return value means the object is on the left padding of the parent, and not on the left edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_x(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the y coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of 'obj' from the top side of its parent plus the parent's top padding
|
||||
* @note Zero return value means the object is on the top padding of the parent, and not on the top edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_y(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the width in pixels
|
||||
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the height in pixels
|
||||
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get that width reduced by the left and right padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the width which still fits into the container without causing overflow
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_fit(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get that height reduced by the top an bottom padding.
|
||||
* @param obj pointer to an object
|
||||
* @return the height which still fits into the container without causing overflow
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_fit(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of an object by taking the top and bottom margin into account.
|
||||
* The returned height will be `obj_h + margin_top + margin_bottom`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_margin(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object by taking the left and right margin into account.
|
||||
* The returned width will be `obj_w + margin_left + margin_right`
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_margin(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_width(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_height(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Handle if the size of the internal (virtual) content of an object has changed.
|
||||
* @param obj pointer to an object
|
||||
* @return false: nothing happened; true: refresh happened
|
||||
*/
|
||||
bool _lv_obj_handle_self_size_chg(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
|
||||
* @param obj pointer to an object
|
||||
* @param w_out store the width here. NULL to not calculate width
|
||||
* @param h_out store the height here. NULL to not calculate height
|
||||
*/
|
||||
void _lv_obj_calc_auto_size(struct _lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out);
|
||||
|
||||
/**
|
||||
* Move an object to a given x and y coordinate.
|
||||
* It's the core function to move objects but user should use `lv_obj_set_pos/x/y/..` etc.
|
||||
* @param obj pointer to an object to move
|
||||
* @param x the new x coordinate in pixels
|
||||
* @param y the new y coordinate in pixels
|
||||
* @param notify_parent true: send `LV_SIGNAL_CHILD_CHG` to the parent if `obj` moved; false: do not notify the parent
|
||||
*/
|
||||
void _lv_obj_move_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_parent);
|
||||
|
||||
/**
|
||||
* Reposition the children of an object. (Called recursively)
|
||||
* @param obj pointer to an object which children will be repositioned
|
||||
* @param x_diff x coordinate shift
|
||||
* @param y_diff y coordinate shift
|
||||
*/
|
||||
void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);
|
||||
|
||||
/**
|
||||
* Check if an object is valid grid item or not.
|
||||
* @param obj pointer to an object to check
|
||||
* @return true: grid item; false: not grid item
|
||||
*/
|
||||
bool _lv_obj_is_grid_item(struct _lv_obj_t * obj);
|
||||
|
||||
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_POS_H*/
|
||||
324
src/lv_core/lv_obj_scroll.c
Normal file
324
src/lv_core/lv_obj_scroll.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* @file lv_obj_scroll.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_scroll.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_obj"
|
||||
#define SCROLL_ANIM_TIME_MIN 100 /*ms*/
|
||||
#define SCROLL_ANIM_TIME_MAX 300 /*ms*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void scroll_anim_x_cb(lv_obj_t * obj, lv_anim_value_t v);
|
||||
static void scroll_anim_y_cb(lv_obj_t * obj, lv_anim_value_t v);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
void lv_obj_set_scroll_mode(lv_obj_t * obj, lv_scroll_mode_t mode)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(obj->spec_attr->scroll_mode == mode) return;
|
||||
obj->spec_attr->scroll_mode = mode;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(dir != obj->spec_attr->scroll_dir) {
|
||||
obj->spec_attr->scroll_dir = dir;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_set_snap_align_x(struct _lv_obj_t * obj, lv_snap_align_t align)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->snap_align_x = align;
|
||||
}
|
||||
|
||||
void lv_obj_set_snap_align_y(struct _lv_obj_t * obj, lv_snap_align_t align)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->snap_align_y = align;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_scroll_mode_t lv_obj_get_scroll_mode(const struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->scroll_mode;
|
||||
else return LV_SCROLL_MODE_AUTO;
|
||||
}
|
||||
|
||||
lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->scroll_dir;
|
||||
else return LV_DIR_ALL;
|
||||
}
|
||||
|
||||
lv_snap_align_t lv_obj_get_snap_align_x(const struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->snap_align_x;
|
||||
else return LV_SCROLL_SNAP_ALIGN_NONE;
|
||||
}
|
||||
|
||||
lv_snap_align_t lv_obj_get_snap_align_y(const struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->snap_align_y;
|
||||
else return LV_SCROLL_SNAP_ALIGN_NONE;
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_x(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_y(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.y;
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.y;
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
lv_coord_t child_res = LV_COORD_MIN;
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
if(child) {
|
||||
lv_coord_t y2 = LV_COORD_MIN;
|
||||
while(child) {
|
||||
y2 = LV_MATH_MAX(y2, child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN));
|
||||
child = lv_obj_get_child(obj, child);
|
||||
}
|
||||
|
||||
child_res = y2;
|
||||
}
|
||||
|
||||
|
||||
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
child_res -= (obj->coords.y2 - pad_bottom);
|
||||
|
||||
lv_coord_t self_h = _lv_obj_get_self_height(obj);
|
||||
self_h = self_h - (lv_obj_get_height(obj) - pad_top - pad_bottom);
|
||||
self_h -= lv_obj_get_scroll_y(obj);
|
||||
return LV_MATH_MAX(child_res, self_h);
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
/* Normally can't scroll the object out on the left.
|
||||
* So simply use the current scroll position as "left size"*/
|
||||
if(lv_obj_get_base_dir(obj) != LV_BIDI_DIR_RTL) {
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
/*With RTL base direction scrolling the left is normal so find the left most coordinate*/
|
||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_coord_t child_res = 0;
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
if(child) {
|
||||
lv_coord_t x1 = LV_COORD_MAX;
|
||||
while(child) {
|
||||
x1 = LV_MATH_MIN(x1, child->coords.x1 - lv_obj_get_style_margin_left(child, LV_OBJ_PART_MAIN));
|
||||
child = lv_obj_get_child(obj, child);
|
||||
}
|
||||
child_res = x1;
|
||||
|
||||
child_res = (obj->coords.x1 + pad_left) - child_res;
|
||||
}
|
||||
|
||||
lv_coord_t self_w = _lv_obj_get_self_width(obj);
|
||||
self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left);
|
||||
self_w -= lv_obj_get_scroll_x(obj);
|
||||
|
||||
return LV_MATH_MAX(child_res, self_w);
|
||||
}
|
||||
|
||||
lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
/* With RTL base dir can't scroll to the object out on the right.
|
||||
* So simply use the current scroll position as "right size"*/
|
||||
if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL) {
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
/*With other base direction (LTR) scrolling to the right is normal so find the right most coordinate*/
|
||||
lv_coord_t child_res = LV_COORD_MIN;
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
if(child) {
|
||||
lv_coord_t x2 = LV_COORD_MIN;
|
||||
while(child) {
|
||||
x2 = LV_MATH_MAX(x2, child->coords.x2 + lv_obj_get_style_margin_right(child, LV_OBJ_PART_MAIN));
|
||||
child = lv_obj_get_child(obj, child);
|
||||
}
|
||||
child_res = x2;
|
||||
|
||||
}
|
||||
|
||||
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN);
|
||||
|
||||
child_res -= (obj->coords.x2 - pad_right);
|
||||
|
||||
lv_coord_t self_w;
|
||||
self_w = _lv_obj_get_self_width(obj);
|
||||
self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left);
|
||||
self_w -= lv_obj_get_scroll_x(obj);
|
||||
return LV_MATH_MAX(child_res, self_w);
|
||||
}
|
||||
|
||||
void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end)
|
||||
{
|
||||
lv_anim_t * a;
|
||||
a = lv_anim_get(obj, (lv_anim_exec_xcb_t)scroll_anim_x_cb);
|
||||
end->x = a ? -a->end : lv_obj_get_scroll_x(obj);
|
||||
|
||||
a = lv_anim_get(obj, (lv_anim_exec_xcb_t)scroll_anim_y_cb);
|
||||
end->y = a ? -a->end : lv_obj_get_scroll_y(obj);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
void _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
if(x == 0 && y == 0) return;
|
||||
|
||||
if(obj->spec_attr == NULL) {
|
||||
obj->spec_attr = lv_obj_allocate_spec_attr(obj);
|
||||
}
|
||||
obj->spec_attr->scroll.x += x;
|
||||
obj->spec_attr->scroll.y += y;
|
||||
|
||||
_lv_obj_move_children_by(obj, x, y);
|
||||
lv_res_t res = lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en)
|
||||
{
|
||||
if(x == 0 && y == 0) return;
|
||||
|
||||
if(anim_en == LV_ANIM_ON) {
|
||||
lv_disp_t * d = lv_obj_get_disp(obj);
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, obj);
|
||||
|
||||
lv_anim_path_t path;
|
||||
lv_anim_path_init(&path);
|
||||
lv_anim_path_set_cb(&path, lv_anim_path_ease_out);
|
||||
|
||||
if(x) {
|
||||
uint32_t t = lv_anim_speed_to_time((lv_disp_get_hor_res(d) * 3) >> 2, 0, x);
|
||||
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
|
||||
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
|
||||
lv_anim_set_time(&a, t);
|
||||
lv_coord_t sx = lv_obj_get_scroll_x(obj);
|
||||
lv_anim_set_values(&a, -sx, -sx + x);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_x_cb);
|
||||
lv_anim_set_path(&a, &path);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
|
||||
if(y) {
|
||||
uint32_t t = lv_anim_speed_to_time((lv_disp_get_ver_res(d) * 3) >> 2, 0, y);
|
||||
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
|
||||
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
|
||||
lv_anim_set_time(&a, t);
|
||||
lv_coord_t sy = lv_obj_get_scroll_y(obj);
|
||||
lv_anim_set_values(&a, -sy, -sy + y);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_y_cb);
|
||||
lv_anim_set_path(&a, &path);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
} else {
|
||||
_lv_obj_scroll_by_raw(obj, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_scroll_to_x(obj, x, anim_en);
|
||||
lv_obj_scroll_to_y(obj, y, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_scroll_by(obj, -x + lv_obj_get_scroll_x(obj), 0, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_scroll_by(obj, 0, -y + lv_obj_get_scroll_y(obj), anim_en);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void scroll_anim_x_cb(lv_obj_t * obj, lv_anim_value_t v)
|
||||
{
|
||||
_lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_x(obj), 0);
|
||||
}
|
||||
|
||||
static void scroll_anim_y_cb(lv_obj_t * obj, lv_anim_value_t v)
|
||||
{
|
||||
_lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_y(obj));
|
||||
}
|
||||
237
src/lv_core/lv_obj_scroll.h
Normal file
237
src/lv_core/lv_obj_scroll.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file lv_obj_scroll.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_SCROLL_H
|
||||
#define LV_OBJ_SCROLL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* Can't include lv_obj.h because it includes this header file */
|
||||
struct _lv_obj_t;
|
||||
|
||||
/** Scrollbar modes: shows when should the scrollbars be visible*/
|
||||
enum {
|
||||
LV_SCROLL_MODE_OFF = 0x0, /**< Never show scroll bars*/
|
||||
LV_SCROLL_MODE_ON = 0x1, /**< Always show scroll bars*/
|
||||
LV_SCROLL_MODE_ACTIVE = 0x2, /**< Show scroll bars when object is being scrolled*/
|
||||
LV_SCROLL_MODE_AUTO = 0x3, /**< Show scroll bars when the content is large enough to be scrolled*/
|
||||
};
|
||||
typedef uint8_t lv_scroll_mode_t;
|
||||
|
||||
|
||||
enum {
|
||||
LV_SCROLL_SNAP_ALIGN_NONE,
|
||||
LV_SCROLL_SNAP_ALIGN_START,
|
||||
LV_SCROLL_SNAP_ALIGN_END,
|
||||
LV_SCROLL_SNAP_ALIGN_CENTER
|
||||
};
|
||||
typedef uint8_t lv_snap_align_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set how the scrollbars should behave.
|
||||
* @param obj pointer to an object
|
||||
* @param mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE
|
||||
*/
|
||||
void lv_obj_set_scroll_mode(struct _lv_obj_t * obj, lv_scroll_mode_t mode);
|
||||
|
||||
/**
|
||||
* Set the object in which directions can be scrolled
|
||||
* @param obj pointer to an object
|
||||
* @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t`
|
||||
*/
|
||||
void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir);
|
||||
|
||||
/**
|
||||
* Set where to snap the children when scrolling ends horizontally
|
||||
* @param obj pointer to an object
|
||||
* @param align the snap align to set from `lv_snap_align_t`
|
||||
*/
|
||||
void lv_obj_set_snap_align_x(struct _lv_obj_t * obj, lv_snap_align_t align);
|
||||
|
||||
/**
|
||||
* Set where to snap the children when scrolling ends vertically
|
||||
* @param obj pointer to an object
|
||||
* @param align the snap align to set from `lv_snap_align_t`
|
||||
*/
|
||||
void lv_obj_set_snap_align_y(struct _lv_obj_t * obj, lv_snap_align_t align);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the current scroll mode (when to hide the scrollbars)
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll mode from `lv_scroll_mode_t`
|
||||
*/
|
||||
lv_scroll_mode_t lv_obj_get_scroll_mode(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the object in which directions can be scrolled
|
||||
* @param obj pointer to an object
|
||||
* @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t`
|
||||
*/
|
||||
lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get where to snap the children when scrolling ends horizontally
|
||||
* @param obj pointer to an object
|
||||
* @return the current snap align from `lv_snap_align_t`
|
||||
*/
|
||||
lv_snap_align_t lv_obj_get_snap_align_x(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get where to snap the children when scrolling ends vertically
|
||||
* @param obj pointer to an object
|
||||
* @return the current snap align from `lv_snap_align_t`
|
||||
*/
|
||||
lv_snap_align_t lv_obj_get_snap_align_y(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get current X scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll position from the left edge.
|
||||
* If the object is not scrolled return 0
|
||||
* If scrolled return > 0
|
||||
* If scrolled in (elastic scroll) return < 0
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_x(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get current Y scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll position from the top edge.
|
||||
* If the object is not scrolled return 0
|
||||
* If scrolled return > 0
|
||||
* If scrolled inside return < 0
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_y(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the height of the area above the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area above the object in pixels
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_top(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the height of the area below the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area below the object in pixels
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_bottom(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the width of the area on the left the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area on the left the object in pixels
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_left(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the width of the area on the right the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area on the right the object in pixels
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_right(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the X and Y coordinates where the scrolling will end for this object if a scrolling animation is in progress.
|
||||
* In no scrolling animation give the current `x` or `y` scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @param end poinr to point to store the result
|
||||
*/
|
||||
void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* The most basic function to scroll by a given amount of pixels
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @note > 0 value means scroll right/bottom (show the right/bottom content)
|
||||
*/
|
||||
void _lv_obj_scroll_by_raw(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
*
|
||||
* Scroll by a given amount of pixels
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
* @note > 0 value means scroll right/bottom (show the right/bottom content)
|
||||
*/
|
||||
void lv_obj_scroll_by(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given coordinate on an object
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given X coordinate on an object
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_x(struct _lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given X coordinate on an object
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_y(struct _lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_SCROLL_H*/
|
||||
1536
src/lv_core/lv_obj_style.c
Normal file
1536
src/lv_core/lv_obj_style.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,331 @@
|
||||
|
||||
/**
|
||||
* @file lv_obj_style_dec.h
|
||||
* @file lv_obj_style.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_STYLE_DEC_H
|
||||
#define LV_OBJ_STYLE_DEC_H
|
||||
#ifndef LV_OBJ_STYLE_H
|
||||
#define LV_OB_STYLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/* Can't include lv_obj.h because it includes this header file */
|
||||
struct _lv_obj_t;
|
||||
|
||||
typedef enum {
|
||||
_LV_STYLE_STATE_CMP_SAME, /*The style properties in the 2 states are identical*/
|
||||
_LV_STYLE_STATE_CMP_VISUAL_DIFF, /*The differences can be shown with a simple redraw*/
|
||||
_LV_STYLE_STATE_CMP_DIFF, /*There are larger differences, the objects need to ne notfied*/
|
||||
} _lv_style_state_cmp_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the object related style manager module.
|
||||
* Called by LVGL in `lv_init()`
|
||||
*/
|
||||
void _lv_obj_style_init(void);
|
||||
|
||||
/**
|
||||
* Add a new style to the style list of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param style pointer to a style to add (Only its pointer will be saved)
|
||||
*/
|
||||
void lv_obj_add_style(lv_obj_t * obj, uint8_t part, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove a style from the style list of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param style pointer to a style to remove
|
||||
*/
|
||||
void lv_obj_remove_style(lv_obj_t * obj, uint8_t part, lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Reset a style to the default (empty) state.
|
||||
* Release all used memories and cancel pending related transitions.
|
||||
* Also notifies the object about the style change.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style list should be reseted.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
*/
|
||||
void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part);
|
||||
|
||||
/**
|
||||
* Notify all object if a style is modified
|
||||
* @param style pointer to a style. Only the objects with this style will be notified
|
||||
* (NULL to notify all objects)
|
||||
*/
|
||||
void lv_obj_report_style_change(lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Remove a local style property from a part of an object with a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be removed.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @return true: the property was found and removed; false: the property was not found
|
||||
*/
|
||||
bool lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Fade in (from transparent to fully cover) an object and all its children using an `opa_scale` animation.
|
||||
* @param obj the object to fade in
|
||||
* @param time duration of the animation [ms]
|
||||
* @param delay wait before the animation starts [ms]
|
||||
*/
|
||||
void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
|
||||
/**
|
||||
* Fade out (from fully cover to transparent) an object and all its children using an `opa_scale` animation.
|
||||
* @param obj the object to fade in
|
||||
* @param time duration of the animation [ms]
|
||||
* @param delay wait before the animation starts [ms]
|
||||
*/
|
||||
void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the style list of part of an object
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @return pointer to the style list
|
||||
*/
|
||||
lv_style_list_t * _lv_obj_get_style_list(const lv_obj_t * obj, uint8_t part);
|
||||
|
||||
/**
|
||||
* Enable/disable the use of style cache for an object
|
||||
* @param obj pointer to an object
|
||||
* @param dis true: disable; false: enable (re-enable)
|
||||
*/
|
||||
void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis);
|
||||
|
||||
|
||||
#if LV_STYLE_CACHE_LEVEL > 0
|
||||
|
||||
/**
|
||||
* Mark the object and all of it's children's style lists as invalid.
|
||||
* The cache will be updated when a cached property asked nest time
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void _lv_obj_invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a style property of a part of an object in the object's current state.
|
||||
* If there is a running transitions it is taken into account
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be get.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop the property to get. E.g. `LV_STYLE_BORDER_WIDTH`.
|
||||
* The state of the object will be added internally
|
||||
* @return the value of the property of the given part in the current state.
|
||||
* If the property is not found a default value will be returned.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_width()`
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Get a style property of a part of an object in the object's current state.
|
||||
* If there is a running transitions it is taken into account
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be get.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop the property to get. E.g. `LV_STYLE_BORDER_COLOR`.
|
||||
* The state of the object will be added internally
|
||||
* @return the value of the property of the given part in the current state.
|
||||
* If the property is not found a default value will be returned.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_color()`
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
lv_color_t _lv_obj_get_style_color(const lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Get a style property of a part of an object in the object's current state.
|
||||
* If there is a running transitions it is taken into account
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be get.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop the property to get. E.g. `LV_STYLE_BORDER_OPA`.
|
||||
* The state of the object will be added internally
|
||||
* @return the value of the property of the given part in the current state.
|
||||
* If the property is not found a default value will be returned.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Get a style property of a part of an object in the object's current state.
|
||||
* If there is a running transitions it is taken into account
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be get.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop the property to get. E.g. `LV_STYLE_TEXT_FONT`.
|
||||
* The state of the object will be added internally
|
||||
* @return the value of the property of the given part in the current state.
|
||||
* If the property is not found a default value will be returned.
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Get the local style of a part of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @return pointer to the local style if exists else `NULL`.
|
||||
*/
|
||||
lv_style_t * _lv_obj_get_local_style(lv_obj_t * obj, uint8_t part);
|
||||
|
||||
/**
|
||||
* Set a local style property of a part of an object in a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_WIDTH | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param the value to set
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_width()`
|
||||
* @note for performance reasons it's not checked if the property really has integer type
|
||||
*/
|
||||
void _lv_obj_set_style_local_int(lv_obj_t * obj, uint8_t part, lv_style_property_t prop, lv_style_int_t value);
|
||||
|
||||
/**
|
||||
* Set a local style property of a part of an object in a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param the value to set
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has color type
|
||||
*/
|
||||
void _lv_obj_set_style_local_color(lv_obj_t * obj, uint8_t part, lv_style_property_t prop, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set a local style property of a part of an object in a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_BORDER_OPA | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param the value to set
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has opacity type
|
||||
*/
|
||||
void _lv_obj_set_style_local_opa(lv_obj_t * obj, uint8_t part, lv_style_property_t prop, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set a local style property of a part of an object in a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be set.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
* @param prop a style property ORed with a state.
|
||||
* E.g. `LV_STYLE_TEXT_FONT | (LV_STATE_PRESSED << LV_STYLE_STATE_POS)`
|
||||
* @param value the value to set
|
||||
* @note shouldn't be used directly. Use the specific property get functions instead.
|
||||
* For example: `lv_obj_style_get_border_opa()`
|
||||
* @note for performance reasons it's not checked if the property really has pointer type
|
||||
*/
|
||||
void _lv_obj_set_style_local_ptr(lv_obj_t * obj, uint8_t part, lv_style_property_t prop, const void * value);
|
||||
|
||||
/**
|
||||
* Reset a style to the default (empty) state.
|
||||
* Release all used memories and cancel pending related transitions.
|
||||
* Typically used in `LV_SIGNAL_CLEAN_UP.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style list should be reseted.
|
||||
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
|
||||
*/
|
||||
void _lv_obj_reset_style_list_no_refr(lv_obj_t * obj, uint8_t part);
|
||||
|
||||
/**
|
||||
* Notify an object and its children about its style is modified
|
||||
* @param obj pointer to an object
|
||||
* @param part the part of the object which style property should be refreshed.
|
||||
* @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed.
|
||||
*/
|
||||
void _lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
|
||||
|
||||
/**
|
||||
* Remove all transitions from an object
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void _lv_obj_remove_style_trans(lv_obj_t * obj);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Allocate and initialize a transition for a property of an object if the properties value is different in the new state.
|
||||
* It allocates `lv_style_trans_t` in `_lv_obj_style_trans_ll` and set only `start/end_values`. No animation will be created here.
|
||||
* @param obj and object to add the transition
|
||||
* @param prop the property to apply the transaction
|
||||
* @param part the part of the object to apply the transaction
|
||||
* @param prev_state the previous state of the objects
|
||||
* @param new_state the new state of the object
|
||||
* @param time duration of transition in [ms]
|
||||
* @param delay delay before starting the transition in [ms]
|
||||
* @param path the path of the transition
|
||||
* @return pointer to the allocated `the transaction` variable or `NULL` if no transition created
|
||||
*/
|
||||
void _lv_obj_create_style_transition(lv_obj_t * obj, lv_style_property_t prop, uint8_t part, lv_state_t prev_state,
|
||||
lv_state_t new_state, uint32_t time, uint32_t delay, lv_anim_path_t * path);
|
||||
|
||||
/**
|
||||
* Compare the style properties of an object in 2 different states
|
||||
* @param obj pointer to an object
|
||||
* @param state1 a state
|
||||
* @param state2 an other state
|
||||
* @return an element of `_lv_style_state_cmp_t`
|
||||
*/
|
||||
_lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Macro to declare the most important style set/get API functions.
|
||||
*
|
||||
@@ -111,7 +422,6 @@ _LV_OBJ_STYLE_SET_GET_DECLARE(PAD_TOP, pad_top, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_BOTTOM, pad_bottom, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_LEFT, pad_left, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_RIGHT, pad_right, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(PAD_INNER, pad_inner, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_TOP, margin_top, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_BOTTOM, margin_bottom, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(MARGIN_LEFT, margin_left, lv_style_int_t, _int, scalar)
|
||||
@@ -198,6 +508,16 @@ _LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_sty
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_GRAD_COLOR, scale_grad_color, lv_color_t, _color, nonscalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCALE_END_COLOR, scale_end_color, lv_color_t, _color, nonscalar)
|
||||
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_TICKNESS, scrollbar_tickness, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_SPACE_SIDE, scrollbar_space_side, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_SPACE_END, scrollbar_space_end, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_RADIUS, scrollbar_radius, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_BORDER_WIDTH, scrollbar_border_width, lv_style_int_t, _int, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_BG_COLOR, scrollbar_bg_color, lv_color_t, _color, nonscalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_BORDER_COLOR, scrollbar_border_color, lv_color_t, _color, nonscalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_BG_OPA, scrollbar_bg_opa, lv_opa_t, _opa, scalar)
|
||||
_LV_OBJ_STYLE_SET_GET_DECLARE(SCROLLBAR_BORDER_OPA, scrollbar_border_opa, lv_opa_t, _opa, scalar)
|
||||
|
||||
#undef _LV_OBJ_STYLE_SET_GET_DECLARE
|
||||
|
||||
|
||||
@@ -300,4 +620,4 @@ static inline void lv_style_set_margin_ver(lv_style_t * style, lv_state_t state,
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_H*/
|
||||
#endif /*LV_TEMPL_H*/
|
||||
@@ -571,7 +571,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(_lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) {
|
||||
if(_lv_area_is_in(area_p, &obj->coords, 0) && lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == false) {
|
||||
lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK);
|
||||
if(design_res == LV_DESIGN_RES_MASKED) return NULL;
|
||||
|
||||
@@ -582,7 +582,8 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
#endif
|
||||
|
||||
lv_obj_t * i;
|
||||
_LV_LL_READ(obj->child_ll, i) {
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(obj);
|
||||
_LV_LL_READ(ll, i) {
|
||||
found_p = lv_refr_get_top_obj(area_p, i);
|
||||
|
||||
/*If a children is ok then break*/
|
||||
@@ -626,13 +627,14 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
|
||||
/*Do until not reach the screen*/
|
||||
while(par != NULL) {
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(par);
|
||||
/*object before border_p has to be redrawn*/
|
||||
lv_obj_t * i = _lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
lv_obj_t * i = _lv_ll_get_prev(ll, border_p);
|
||||
|
||||
while(i != NULL) {
|
||||
/*Refresh the objects*/
|
||||
lv_refr_obj(i, mask_p);
|
||||
i = _lv_ll_get_prev(&(par->child_ll), i);
|
||||
i = _lv_ll_get_prev(ll, i);
|
||||
}
|
||||
|
||||
/*Call the post draw design function of the parents of the to object*/
|
||||
@@ -654,7 +656,7 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
{
|
||||
/*Do not refresh hidden objects*/
|
||||
if(obj->hidden != 0) return;
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return;
|
||||
|
||||
bool union_ok; /* Store the return value of area_union */
|
||||
/* Truncate the original mask to the coordinates of the parent
|
||||
@@ -662,7 +664,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
lv_area_t obj_mask;
|
||||
lv_area_t obj_ext_mask;
|
||||
lv_area_t obj_area;
|
||||
lv_coord_t ext_size = obj->ext_draw_pad;
|
||||
lv_coord_t ext_size = _lv_obj_get_ext_draw_pad(obj);
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
obj_area.x1 -= ext_size;
|
||||
obj_area.y1 -= ext_size;
|
||||
@@ -683,7 +685,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
draw_dsc.bg_color.full = debug_color.full;
|
||||
draw_dsc.bg_opa = LV_OPA_20;
|
||||
draw_dsc.border_width = 2;
|
||||
draw_dsc.border_opa = LV_OPA_50;
|
||||
draw_dsc.border_opa = LV_OPA_70;
|
||||
draw_dsc.border_color.full = (debug_color.full + 0x13) * 9;
|
||||
|
||||
lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &draw_dsc);
|
||||
@@ -700,9 +702,10 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
lv_area_t mask_child; /*Mask from obj and its child*/
|
||||
lv_obj_t * child_p;
|
||||
lv_area_t child_area;
|
||||
_LV_LL_READ_BACK(obj->child_ll, child_p) {
|
||||
lv_ll_t * ll = _lv_obj_get_child_ll(obj);
|
||||
_LV_LL_READ_BACK(ll, child_p) {
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_draw_pad;
|
||||
ext_size = _lv_obj_get_ext_draw_pad(child_p);
|
||||
child_area.x1 -= ext_size;
|
||||
child_area.y1 -= ext_size;
|
||||
child_area.x2 += ext_size;
|
||||
|
||||
@@ -1045,6 +1045,7 @@ bool lv_debug_check_style_list(const lv_style_list_t * list)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static uint32_t stat[256];
|
||||
/**
|
||||
* Get a property's index (byte index in `style->map`) from a style.
|
||||
* Return best matching property's index considering the state of `prop`
|
||||
@@ -1068,6 +1069,12 @@ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
stat[prop & 0xFF]++;
|
||||
//
|
||||
if((prop & 0xFF) == LV_STYLE_PAD_TOP) {
|
||||
// printf("pad top\n");
|
||||
}
|
||||
|
||||
uint8_t prop_id;
|
||||
while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) {
|
||||
if(prop_id == id_to_find) {
|
||||
|
||||
@@ -45,6 +45,10 @@ LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||
|
||||
#define LV_STYLE_PROP_ALL 0xFF
|
||||
|
||||
#if LV_STYLE_CACHE_LEVEL >= 2
|
||||
#define _LV_STLYE_CAHCE_INT_MAX 63
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -106,11 +110,10 @@ enum {
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_LEFT, 0x1, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_RIGHT, 0x1, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_PAD_INNER, 0x1, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_TOP, 0x1, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_LEFT, 0x1, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_RIGHT, 0x1, LV_STYLE_ID_VALUE + 8, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_TOP, 0x1, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 5, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_LEFT, 0x1, LV_STYLE_ID_VALUE + 6, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_MARGIN_RIGHT, 0x1, LV_STYLE_ID_VALUE + 7, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_BLEND_MODE, 0x2, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_BG_MAIN_STOP, 0x2, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
@@ -198,6 +201,16 @@ enum {
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_LINE_WIDTH, 0xC, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_GRAD_COLOR, 0xC, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_COLOR, 0xC, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_TICKNESS, 0xD, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_SPACE_SIDE, 0xD, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_SPACE_END, 0xD, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_RADIUS, 0xD, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_BORDER_WIDTH, 0xD, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_BG_COLOR, 0xD, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_BORDER_COLOR, 0xD, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_BG_OPA, 0xD, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
|
||||
LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_BORDER_OPA, 0xD, LV_STYLE_ID_OPA + 1, LV_STYLE_ATTR_NONE),
|
||||
};
|
||||
|
||||
typedef uint16_t lv_style_property_t;
|
||||
@@ -222,14 +235,17 @@ typedef struct {
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t sentinel;
|
||||
#endif
|
||||
uint32_t style_cnt : 6;
|
||||
uint32_t style_cnt : 5;
|
||||
uint32_t has_local : 1;
|
||||
uint32_t has_trans : 1;
|
||||
uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/
|
||||
uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/
|
||||
|
||||
#if LV_STYLE_CACHE_LEVEL >= 1
|
||||
uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/
|
||||
uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/
|
||||
|
||||
/*32 properties*/
|
||||
uint32_t radius_zero : 1;
|
||||
uint32_t opa_scale_cover : 1;
|
||||
uint32_t clip_corner_off : 1;
|
||||
@@ -253,6 +269,13 @@ typedef struct {
|
||||
uint32_t text_space_zero : 1;
|
||||
uint32_t text_decor_none : 1;
|
||||
uint32_t text_font_normal : 1;
|
||||
#endif
|
||||
|
||||
#if LV_STYLE_CACHE_LEVEL >= 2
|
||||
uint32_t pad_top :6;
|
||||
uint32_t pad_left :6;
|
||||
#endif
|
||||
|
||||
} lv_style_list_t;
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -99,8 +99,8 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
|
||||
return;
|
||||
}
|
||||
|
||||
if(start_angle >= 360) start_angle -= 360;
|
||||
if(end_angle >= 360) end_angle -= 360;
|
||||
while(start_angle >= 360) start_angle -= 360;
|
||||
while(end_angle >= 360) end_angle -= 360;
|
||||
|
||||
lv_draw_mask_angle_param_t mask_angle_param;
|
||||
lv_draw_mask_angle_init(&mask_angle_param, center_x, center_y, start_angle, end_angle);
|
||||
|
||||
@@ -95,7 +95,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
lv_img_decoder_t * d;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
res = LV_RES_INV;
|
||||
if(d->info_cb) {
|
||||
res = d->info_cb(d, src, header);
|
||||
@@ -136,7 +136,7 @@ lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_co
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
lv_img_decoder_t * d;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_img_defoder_ll), d) {
|
||||
/*Info an Open callbacks are required*/
|
||||
if(d->info_cb == NULL || d->open_cb == NULL) continue;
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct _lv_font_struct {
|
||||
uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/
|
||||
|
||||
int8_t underline_position; /**< Distance between the top of the underline and base line (< 0 means below the base line)*/
|
||||
int8_t underline_thickness; /**< Thickness of the underline*/
|
||||
int8_t underline_thickness; /**< Thickness of the underline*/
|
||||
|
||||
void * dsc; /**< Store implementation specific or run_time data or caching here*/
|
||||
#if LV_USE_USER_DATA
|
||||
|
||||
@@ -158,8 +158,11 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
|
||||
lv_obj_reset_style_list(disp->top_layer, LV_OBJ_PART_MAIN);
|
||||
lv_obj_reset_style_list(disp->sys_layer, LV_OBJ_PART_MAIN);
|
||||
lv_obj_set_click(disp->top_layer, false);
|
||||
lv_obj_set_click(disp->sys_layer, false);
|
||||
lv_obj_clear_flag(disp->top_layer, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_clear_flag(disp->sys_layer, LV_OBJ_FLAG_CLICKABLE);
|
||||
|
||||
lv_obj_set_scroll_mode(disp->top_layer, LV_SCROLL_MODE_OFF);
|
||||
lv_obj_set_scroll_mode(disp->sys_layer, LV_SCROLL_MODE_OFF);
|
||||
|
||||
lv_obj_invalidate(disp->act_scr);
|
||||
|
||||
@@ -185,7 +188,7 @@ void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)
|
||||
memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));
|
||||
|
||||
lv_obj_t * scr;
|
||||
_LV_LL_READ(disp->scr_ll, scr) {
|
||||
_LV_LL_READ(&disp->scr_ll, scr) {
|
||||
lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||||
_lv_memset_00(driver, sizeof(lv_indev_drv_t));
|
||||
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
driver->drag_throw = LV_INDEV_DEF_DRAG_THROW;
|
||||
driver->scroll_limit = LV_INDEV_DEF_DRAG_LIMIT;
|
||||
driver->scroll_throw = LV_INDEV_DEF_DRAG_THROW;
|
||||
driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
|
||||
driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
|
||||
driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
|
||||
|
||||
@@ -50,15 +50,13 @@ typedef uint8_t lv_indev_type_t;
|
||||
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
|
||||
typedef uint8_t lv_indev_state_t;
|
||||
|
||||
|
||||
enum {
|
||||
LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */
|
||||
LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */
|
||||
LV_DRAG_DIR_BOTH = 0x3, /**< Object can be dragged in all directions. */
|
||||
LV_DRAG_DIR_ONE = 0x4, /**< Object can be dragged only one direction (the first move). */
|
||||
LV_SCROLL_DIR_NONE,
|
||||
LV_SCROLL_DIR_HOR,
|
||||
LV_SCROLL_DIR_VER,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_drag_dir_t;
|
||||
typedef uint8_t lv_scroll_dir_t;
|
||||
|
||||
enum {
|
||||
LV_GESTURE_DIR_TOP, /**< Gesture dir up. */
|
||||
@@ -105,10 +103,10 @@ typedef struct _lv_indev_drv_t {
|
||||
lv_task_t * read_task;
|
||||
|
||||
/**< Number of pixels to slide before actually drag the object*/
|
||||
uint8_t drag_limit;
|
||||
uint8_t scroll_limit;
|
||||
|
||||
/**< Drag throw slow-down in [%]. Greater value means faster slow-down */
|
||||
uint8_t drag_throw;
|
||||
uint8_t scroll_throw;
|
||||
|
||||
/**< At least this difference should between two points to evaluate as gesture */
|
||||
uint8_t gesture_min_velocity;
|
||||
@@ -134,19 +132,20 @@ typedef struct _lv_indev_proc_t {
|
||||
lv_point_t act_point; /**< Current point of input device. */
|
||||
lv_point_t last_point; /**< Last point of input device. */
|
||||
lv_point_t vect; /**< Difference between `act_point` and `last_point`. */
|
||||
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t drag_throw_vect;
|
||||
lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
|
||||
lv_point_t scroll_throw_vect;
|
||||
lv_point_t scroll_throw_vect_ori;
|
||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_obj; /*The last object which was pressed (used by drag_throw and
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * scroll_obj; /*The object being scrolled*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
lv_area_t scroll_area;
|
||||
|
||||
lv_gesture_dir_t gesture_dir;
|
||||
lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
|
||||
/*Flags*/
|
||||
uint8_t drag_limit_out : 1;
|
||||
uint8_t drag_in_prog : 1;
|
||||
lv_drag_dir_t drag_dir : 3;
|
||||
lv_scroll_dir_t scroll_dir : 2;
|
||||
uint8_t gesture_sent : 1;
|
||||
} pointer;
|
||||
struct {
|
||||
|
||||
@@ -162,7 +162,7 @@ bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb)
|
||||
{
|
||||
lv_anim_t * a;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
if(a->var == var && a->exec_cb == exec_cb) {
|
||||
return a;
|
||||
}
|
||||
@@ -179,7 +179,7 @@ uint16_t lv_anim_count_running(void)
|
||||
{
|
||||
uint16_t cnt = 0;
|
||||
lv_anim_t * a;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++;
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) cnt++;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
@@ -260,7 +260,7 @@ lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 1, 1, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 0, 1024 * 1 / 3, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -287,7 +287,7 @@ lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 1024 * 2 / 3, 1024, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -314,7 +314,7 @@ lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_a
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 100, 924, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 64, 1024 - 64, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
@@ -444,7 +444,7 @@ static void anim_task(lv_task_t * param)
|
||||
(void)param;
|
||||
|
||||
lv_anim_t * a;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
a->has_run = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*To avoid overflow don't let the max ranges (reduce with 1000) */
|
||||
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
|
||||
#define _LV_COORD_MAX_REDUCE 8192
|
||||
/*To allow some special values in the end reduce the max value */
|
||||
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - _LV_COORD_MAX_REDUCE))
|
||||
#define LV_COORD_MIN (-LV_COORD_MAX)
|
||||
|
||||
LV_EXPORT_CONST_INT(LV_COORD_MAX);
|
||||
@@ -77,6 +78,19 @@ enum {
|
||||
};
|
||||
typedef uint8_t lv_align_t;
|
||||
|
||||
enum {
|
||||
LV_DIR_NONE = 0x00,
|
||||
LV_DIR_LEFT = (1 << 0),
|
||||
LV_DIR_RIGHT = (1 << 1),
|
||||
LV_DIR_TOP = (1 << 2),
|
||||
LV_DIR_BOTTOM = (1 << 3),
|
||||
LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT,
|
||||
LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM,
|
||||
LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_dir_t;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
@@ -208,6 +222,34 @@ void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define _LV_COORD_TYPE_SHIFT (13)
|
||||
#define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_PX (0 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_GRID (1 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_FLEX (2 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_SPEC (3 << _LV_COORD_TYPE_SHIFT)
|
||||
|
||||
#define LV_COORD_IS_PX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_PX) ? true : false)
|
||||
#define LV_COORD_IS_GRID(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_GRID) ? true : false)
|
||||
#define LV_COORD_IS_FLEX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_FLEX) ? true : false)
|
||||
#define LV_COORD_IS_SPEC(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_SPEC) ? true : false)
|
||||
|
||||
#define LV_COORD_GET_PX(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_GRID(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_FLEX(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_SPEC(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
|
||||
#define _LV_COORD_GRID(x) (_LV_COORD_TYPE_GRID | (x))
|
||||
#define _LV_COORD_FELX(x) (_LV_COORD_TYPE_FLEX | (x))
|
||||
#define _LV_COORD_SPEC(x) (_LV_COORD_TYPE_SPEC | (x))
|
||||
|
||||
/*Special coordinates*/
|
||||
#define LV_COORD_PCT(x) _LV_COORD_SPEC((x))
|
||||
#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && LV_COORD_GET_SPEC(x) <= 1000) ? true : false)
|
||||
#define _LV_COORD_GET_PCT(x) LV_COORD_GET_SPEC(x)
|
||||
#define LV_SIZE_AUTO _LV_COORD_SPEC(1001)
|
||||
#define LV_SIZE_STRETCH _LV_COORD_SPEC(1002)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -503,7 +503,7 @@ lv_fs_drv_t * lv_fs_get_drv(char letter)
|
||||
{
|
||||
lv_fs_drv_t * drv;
|
||||
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
if(drv->letter == letter) {
|
||||
return drv;
|
||||
}
|
||||
@@ -521,7 +521,7 @@ char * lv_fs_get_letters(char * buf)
|
||||
lv_fs_drv_t * drv;
|
||||
uint8_t i = 0;
|
||||
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_drv_ll), drv) {
|
||||
buf[i] = drv->letter;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,8 @@ void * _lv_ll_ins_tail(lv_ll_t * ll_p)
|
||||
*/
|
||||
void _lv_ll_remove(lv_ll_t * ll_p, void * node_p)
|
||||
{
|
||||
if(ll_p == NULL) return;
|
||||
|
||||
if(_lv_ll_get_head(ll_p) == node_p) {
|
||||
/*The new head will be the node after 'n_act'*/
|
||||
ll_p->head = _lv_ll_get_next(ll_p, node_p);
|
||||
@@ -256,13 +258,8 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h
|
||||
*/
|
||||
void * _lv_ll_get_head(const lv_ll_t * ll_p)
|
||||
{
|
||||
void * head = NULL;
|
||||
|
||||
if(ll_p != NULL) {
|
||||
head = ll_p->head;
|
||||
}
|
||||
|
||||
return head;
|
||||
if(ll_p == NULL) return NULL;
|
||||
return ll_p->head;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,15 +269,9 @@ void * _lv_ll_get_head(const lv_ll_t * ll_p)
|
||||
*/
|
||||
void * _lv_ll_get_tail(const lv_ll_t * ll_p)
|
||||
{
|
||||
void * tail = NULL;
|
||||
|
||||
if(ll_p != NULL) {
|
||||
tail = ll_p->tail;
|
||||
}
|
||||
|
||||
return tail;
|
||||
if(ll_p == NULL) return NULL;
|
||||
return ll_p->tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the pointer of the next node after 'n_act'
|
||||
* @param ll_p pointer to linked list
|
||||
@@ -289,8 +280,6 @@ void * _lv_ll_get_tail(const lv_ll_t * ll_p)
|
||||
*/
|
||||
void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)
|
||||
{
|
||||
if(ll_p == NULL) return NULL;
|
||||
|
||||
/* Pointer to the next node is stored in the end of this node.
|
||||
* Go there and return the address found there */
|
||||
const lv_ll_node_t * n_act_d = n_act;
|
||||
@@ -306,8 +295,6 @@ void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)
|
||||
*/
|
||||
void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act)
|
||||
{
|
||||
if(ll_p == NULL) return NULL;
|
||||
|
||||
/* Pointer to the prev. node is stored in the end of this node.
|
||||
* Go there and return the address found there */
|
||||
const lv_ll_node_t * n_act_d = n_act;
|
||||
|
||||
@@ -157,9 +157,9 @@ bool _lv_ll_is_empty(lv_ll_t * ll_p);
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define _LV_LL_READ(list, i) for(i = _lv_ll_get_head(&list); i != NULL; i = _lv_ll_get_next(&list, i))
|
||||
#define _LV_LL_READ(list, i) for((i) = _lv_ll_get_head(list); i != NULL; (i) = _lv_ll_get_next(list, i))
|
||||
|
||||
#define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(&list); i != NULL; i = _lv_ll_get_prev(&list, i))
|
||||
#define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(list); i != NULL; i = _lv_ll_get_prev(list, i))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef LV_MEM_FULL_DEFRAG_CNT
|
||||
#define LV_MEM_FULL_DEFRAG_CNT 16
|
||||
#define LV_MEM_FULL_DEFRAG_CNT 64
|
||||
#endif
|
||||
|
||||
#ifdef LV_ARCH_64
|
||||
@@ -72,8 +72,9 @@ typedef struct {
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
static void * alloc_core(size_t size);
|
||||
static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e);
|
||||
static void * ent_alloc(lv_mem_ent_t * e, size_t size);
|
||||
static inline void * ent_alloc(lv_mem_ent_t * e, size_t size);
|
||||
static void ent_trunc(lv_mem_ent_t * e, size_t size);
|
||||
#endif
|
||||
|
||||
@@ -82,11 +83,12 @@ typedef struct {
|
||||
**********************/
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
static uint8_t * work_mem;
|
||||
static lv_mem_ent_t * last_ent;
|
||||
#endif
|
||||
|
||||
static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/
|
||||
|
||||
static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
static uint8_t * last_mem; /*Address of the last valid byte*/
|
||||
static uint32_t mem_max_size; /*Tracks the maximum total size of memory ever used from the internal heap*/
|
||||
#endif
|
||||
|
||||
@@ -125,7 +127,7 @@ void _lv_mem_init(void)
|
||||
#else
|
||||
work_mem = (uint8_t *)LV_MEM_ADR;
|
||||
#endif
|
||||
|
||||
last_mem = &work_mem[LV_MEM_SIZE - 1];
|
||||
lv_mem_ent_t * full = (lv_mem_ent_t *)work_mem;
|
||||
full->header.s.used = 0;
|
||||
/*The total mem size id reduced by the first header and the close patterns */
|
||||
@@ -159,6 +161,11 @@ void * lv_mem_alloc(size_t size)
|
||||
return &zero_mem;
|
||||
}
|
||||
|
||||
// last_ent = NULL;
|
||||
static uint32_t c = 0;
|
||||
c++;
|
||||
// if(c%10 == 0) printf("alloc:%d\n", c);
|
||||
|
||||
#ifdef LV_ARCH_64
|
||||
/*Round the size up to 8*/
|
||||
size = (size + 7) & (~0x7);
|
||||
@@ -169,20 +176,12 @@ void * lv_mem_alloc(size_t size)
|
||||
void * alloc = NULL;
|
||||
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/*Use the built-in allocators*/
|
||||
lv_mem_ent_t * e = NULL;
|
||||
|
||||
/* Search for a appropriate entry*/
|
||||
do {
|
||||
/* Get the next entry*/
|
||||
e = ent_get_next(e);
|
||||
|
||||
/*If there is next entry then try to allocate there*/
|
||||
if(e != NULL) {
|
||||
alloc = ent_alloc(e, size);
|
||||
}
|
||||
/* End if there is not next entry OR the alloc. is successful*/
|
||||
} while(e != NULL && alloc == NULL);
|
||||
alloc = alloc_core(size);
|
||||
if(alloc == NULL) {
|
||||
LV_LOG_TRACE("No more memory, try to defrag");
|
||||
lv_mem_defrag();
|
||||
alloc = alloc_core(size);
|
||||
}
|
||||
|
||||
#else
|
||||
/*Use custom, user defined malloc function*/
|
||||
@@ -205,7 +204,12 @@ void * lv_mem_alloc(size_t size)
|
||||
#endif
|
||||
|
||||
if(alloc == NULL) {
|
||||
LV_LOG_WARN("Couldn't allocate memory");
|
||||
LV_LOG_WARN("Couldn't allocate memory (%d bytes)", size);
|
||||
lv_mem_monitor_t mon;
|
||||
lv_mem_monitor(&mon);
|
||||
LV_LOG_WARN("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n",
|
||||
(int)mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct,
|
||||
(int)mon.free_biggest_size);
|
||||
}
|
||||
else {
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
@@ -230,45 +234,26 @@ void lv_mem_free(const void * data)
|
||||
if(data == &zero_mem) return;
|
||||
if(data == NULL) return;
|
||||
|
||||
#if LV_MEM_ADD_JUNK
|
||||
_lv_memset((void *)data, 0xbb, _lv_mem_get_size(data));
|
||||
#endif
|
||||
|
||||
#if LV_ENABLE_GC == 0
|
||||
/*e points to the header*/
|
||||
lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t));
|
||||
e->header.s.used = 0;
|
||||
# if LV_MEM_ADD_JUNK
|
||||
_lv_memset((void *)data, 0xbb, _lv_mem_get_size(data));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
#if LV_MEM_AUTO_DEFRAG
|
||||
static uint16_t full_defrag_cnt = 0;
|
||||
full_defrag_cnt++;
|
||||
if(full_defrag_cnt < LV_MEM_FULL_DEFRAG_CNT) {
|
||||
/* Make a simple defrag.
|
||||
* Join the following free entries after this*/
|
||||
lv_mem_ent_t * e_next;
|
||||
e_next = ent_get_next(e);
|
||||
while(e_next != NULL) {
|
||||
if(e_next->header.s.used == 0) {
|
||||
e->header.s.d_size += e_next->header.s.d_size + sizeof(e->header);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
e_next = ent_get_next(e_next);
|
||||
}
|
||||
}
|
||||
else {
|
||||
full_defrag_cnt = 0;
|
||||
e->header.s.used = 0;
|
||||
|
||||
static uint32_t defr = 0;
|
||||
defr++;
|
||||
if(defr > LV_MEM_FULL_DEFRAG_CNT) {
|
||||
defr = 0;
|
||||
lv_mem_defrag();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /*LV_MEM_AUTO_DEFRAG*/
|
||||
#else /*Use custom, user defined free function*/
|
||||
#else
|
||||
#if LV_ENABLE_GC == 0
|
||||
/*e points to the header*/
|
||||
LV_MEM_CUSTOM_FREE(e);
|
||||
#else
|
||||
LV_MEM_CUSTOM_FREE((void *)data);
|
||||
@@ -356,6 +341,7 @@ void lv_mem_defrag(void)
|
||||
lv_mem_ent_t * e_free;
|
||||
lv_mem_ent_t * e_next;
|
||||
e_free = ent_get_next(NULL);
|
||||
last_ent = NULL;
|
||||
|
||||
while(1) {
|
||||
/*Search the next free entry*/
|
||||
@@ -369,6 +355,7 @@ void lv_mem_defrag(void)
|
||||
}
|
||||
|
||||
if(e_free == NULL) return;
|
||||
if(last_ent == NULL) last_ent = e_free;
|
||||
|
||||
/*Joint the following free entries to the free*/
|
||||
e_next = ent_get_next(e_free);
|
||||
@@ -397,7 +384,7 @@ lv_res_t lv_mem_test(void)
|
||||
lv_mem_ent_t * e;
|
||||
e = ent_get_next(NULL);
|
||||
while(e) {
|
||||
if(e->header.s.d_size > LV_MEM_SIZE) {
|
||||
if( e->header.s.d_size > LV_MEM_SIZE) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
uint8_t * e8 = (uint8_t *) e;
|
||||
@@ -810,6 +797,30 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len)
|
||||
**********************/
|
||||
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
|
||||
static void * alloc_core(size_t size)
|
||||
{
|
||||
void * alloc = NULL;
|
||||
|
||||
// lv_mem_ent_t * e = NULL;
|
||||
lv_mem_ent_t * e = last_ent;
|
||||
|
||||
/* Search for a appropriate entry*/
|
||||
if(e == NULL) e = ent_get_next(NULL);
|
||||
do {
|
||||
/* Get the next entry*/
|
||||
/*If there is next entry then try to allocate there*/
|
||||
if(!e->header.s.used && e->header.s.d_size >= size) alloc = ent_alloc(e, size);
|
||||
|
||||
e = ent_get_next(e);
|
||||
if( e == NULL) break;
|
||||
|
||||
/* End if the alloc. is successful*/
|
||||
} while(alloc == NULL);
|
||||
last_ent = e;
|
||||
|
||||
return alloc;
|
||||
}
|
||||
/**
|
||||
* Give the next entry after 'act_e'
|
||||
* @param act_e pointer to an entry
|
||||
@@ -817,19 +828,15 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len)
|
||||
*/
|
||||
static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e)
|
||||
{
|
||||
lv_mem_ent_t * next_e = NULL;
|
||||
|
||||
if(act_e == NULL) { /*NULL means: get the first entry*/
|
||||
next_e = (lv_mem_ent_t *)work_mem;
|
||||
}
|
||||
else { /*Get the next entry */
|
||||
/*NULL means: get the first entry; else get the next after `act_e`*/
|
||||
if(act_e == NULL) return (lv_mem_ent_t *)work_mem;
|
||||
else {
|
||||
uint8_t * data = &act_e->first_data;
|
||||
next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size];
|
||||
lv_mem_ent_t * next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size];
|
||||
|
||||
if(&next_e->first_data >= &work_mem[LV_MEM_SIZE]) next_e = NULL;
|
||||
if(&next_e->first_data > last_mem) return NULL;
|
||||
else return next_e;
|
||||
}
|
||||
|
||||
return next_e;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -838,20 +845,23 @@ static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e)
|
||||
* @param size size of the new memory in bytes
|
||||
* @return pointer to the allocated memory or NULL if not enough memory in the entry
|
||||
*/
|
||||
static void * ent_alloc(lv_mem_ent_t * e, size_t size)
|
||||
static inline void * ent_alloc(lv_mem_ent_t * e, size_t size)
|
||||
{
|
||||
void * alloc = NULL;
|
||||
/*If the memory is free and big enough then use it */
|
||||
if(e->header.s.used == 0 && e->header.s.d_size >= size) {
|
||||
// static uint32_t cnt = 0;
|
||||
//
|
||||
//// if((cnt & 0xFFFF) == 0)
|
||||
// printf("alloc: %d\n", cnt);
|
||||
// cnt++;
|
||||
//
|
||||
|
||||
|
||||
/*Truncate the entry to the desired size */
|
||||
ent_trunc(e, size);
|
||||
e->header.s.used = 1;
|
||||
|
||||
/*Save the allocated data*/
|
||||
alloc = &e->first_data;
|
||||
}
|
||||
return &e->first_data;
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -305,7 +305,7 @@ void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio)
|
||||
|
||||
/*Find the tasks with new priority*/
|
||||
lv_task_t * i;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i) {
|
||||
_LV_LL_READ(&LV_GC_ROOT(_lv_task_ll), i) {
|
||||
if(i->prio <= prio) {
|
||||
if(i != task) _lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, i);
|
||||
break;
|
||||
@@ -407,6 +407,7 @@ static bool lv_task_exec(lv_task_t * task)
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
if(task->task_cb) task->task_cb(task);
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
|
||||
/*Delete if it was a one shot lv_task*/
|
||||
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
||||
|
||||
@@ -206,269 +206,143 @@ static void clear_styles(lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
|
||||
case LV_THEME_SCR:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_OBJ_PART_MAIN);
|
||||
break;
|
||||
case LV_THEME_OBJ:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_OBJ_PART_MAIN);
|
||||
break;
|
||||
#if LV_USE_CONT
|
||||
case LV_THEME_CONT:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTN
|
||||
case LV_THEME_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_BTN_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTNMATRIX
|
||||
case LV_THEME_BTNMATRIX:
|
||||
lv_obj_clean_style_list(obj, LV_BTNMATRIX_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_KEYBOARD
|
||||
case LV_THEME_KEYBOARD:
|
||||
lv_obj_clean_style_list(obj, LV_KEYBOARD_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_KEYBOARD_PART_BTN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_BTNMATRIX_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_BTNMATRIX_PART_BTN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BAR
|
||||
case LV_THEME_BAR:
|
||||
lv_obj_clean_style_list(obj, LV_BAR_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_BAR_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
case LV_THEME_SWITCH:
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CANVAS
|
||||
case LV_THEME_CANVAS:
|
||||
lv_obj_clean_style_list(obj, LV_CANVAS_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SWITCH_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SWITCH_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SWITCH_PART_KNOB);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMG
|
||||
case LV_THEME_IMAGE:
|
||||
lv_obj_clean_style_list(obj, LV_IMG_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMGBTN
|
||||
case LV_THEME_IMGBTN:
|
||||
lv_obj_clean_style_list(obj, LV_IMG_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL
|
||||
case LV_THEME_LABEL:
|
||||
lv_obj_clean_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINE
|
||||
case LV_THEME_LINE:
|
||||
lv_obj_clean_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_ARC
|
||||
case LV_THEME_ARC:
|
||||
lv_obj_clean_style_list(obj, LV_ARC_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_ARC_PART_INDIC);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPINNER
|
||||
case LV_THEME_SPINNER:
|
||||
lv_obj_clean_style_list(obj, LV_SPINNER_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_SPINNER_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_ARC_PART_BG);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_ARC_PART_INDIC);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
case LV_THEME_SLIDER:
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SLIDER_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SLIDER_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_SLIDER_PART_KNOB);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
case LV_THEME_CHECKBOX:
|
||||
lv_obj_clean_style_list(obj, LV_CHECKBOX_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_CHECKBOX_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_CHECKBOX_PART_BULLET);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MSGBOX
|
||||
case LV_THEME_MSGBOX:
|
||||
lv_obj_clean_style_list(obj, LV_MSGBOX_PART_BG);
|
||||
break;
|
||||
|
||||
case LV_THEME_MSGBOX_BTNS:
|
||||
lv_obj_clean_style_list(obj, LV_MSGBOX_PART_BTN_BG);
|
||||
lv_obj_clean_style_list(obj, LV_MSGBOX_PART_BTN);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if LV_USE_LED
|
||||
case LV_THEME_LED:
|
||||
lv_obj_clean_style_list(obj, LV_LED_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_PAGE
|
||||
case LV_THEME_PAGE:
|
||||
lv_obj_clean_style_list(obj, LV_PAGE_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
lv_obj_clean_style_list(obj, LV_PAGE_PART_SCROLLBAR);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABVIEW
|
||||
case LV_THEME_TABVIEW:
|
||||
lv_obj_clean_style_list(obj, LV_TABVIEW_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_TABVIEW_PART_BG_SCRLLABLE);
|
||||
lv_obj_clean_style_list(obj, LV_TABVIEW_PART_TAB_BG);
|
||||
lv_obj_clean_style_list(obj, LV_TABVIEW_PART_INDIC);
|
||||
lv_obj_clean_style_list(obj, LV_TABVIEW_PART_TAB_BTN);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABVIEW_PAGE:
|
||||
lv_obj_clean_style_list(obj, LV_PAGE_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TILEVIEW
|
||||
case LV_THEME_TILEVIEW:
|
||||
lv_obj_clean_style_list(obj, LV_TILEVIEW_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_TILEVIEW_PART_SCROLLBAR);
|
||||
lv_obj_clean_style_list(obj, LV_TILEVIEW_PART_EDGE_FLASH);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
case LV_THEME_ROLLER:
|
||||
lv_obj_clean_style_list(obj, LV_ROLLER_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_ROLLER_PART_BG);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_ROLLER_PART_SELECTED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_OBJMASK
|
||||
case LV_THEME_OBJMASK:
|
||||
lv_obj_clean_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIST
|
||||
case LV_THEME_LIST:
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_SCROLLABLE);
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DROPDOWN
|
||||
case LV_THEME_DROPDOWN:
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_DROPDOWN_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_DROPDOWN_PART_LIST);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
case LV_THEME_CHART:
|
||||
lv_obj_clean_style_list(obj, LV_CHART_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
lv_obj_clean_style_list(obj, LV_CHART_PART_SERIES);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_CHART_PART_BG);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_CHART_PART_SERIES_BG);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_CHART_PART_SERIES);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
case LV_THEME_TABLE:
|
||||
lv_obj_clean_style_list(obj, LV_TABLE_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_TABLE_PART_CELL1);
|
||||
lv_obj_clean_style_list(obj, LV_TABLE_PART_CELL2);
|
||||
lv_obj_clean_style_list(obj, LV_TABLE_PART_CELL3);
|
||||
lv_obj_clean_style_list(obj, LV_TABLE_PART_CELL4);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_WIN
|
||||
case LV_THEME_WIN:
|
||||
lv_obj_clean_style_list(obj, LV_WIN_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_WIN_PART_SCROLLBAR);
|
||||
lv_obj_clean_style_list(obj, LV_WIN_PART_CONTENT_SCROLLABLE);
|
||||
lv_obj_clean_style_list(obj, LV_WIN_PART_HEADER);
|
||||
break;
|
||||
|
||||
case LV_THEME_WIN_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TABLE_PART_BG);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TABLE_PART_CELL1);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TABLE_PART_CELL2);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TABLE_PART_CELL3);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TABLE_PART_CELL4);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA
|
||||
case LV_THEME_TEXTAREA:
|
||||
lv_obj_clean_style_list(obj, LV_TEXTAREA_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
lv_obj_clean_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
lv_obj_clean_style_list(obj, LV_TEXTAREA_PART_SCROLLBAR);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_SPINBOX
|
||||
case LV_THEME_SPINBOX:
|
||||
lv_obj_clean_style_list(obj, LV_SPINBOX_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_SPINBOX_PART_CURSOR);
|
||||
break;
|
||||
|
||||
case LV_THEME_SPINBOX_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
case LV_THEME_CALENDAR:
|
||||
lv_obj_clean_style_list(obj, LV_CALENDAR_PART_BG);
|
||||
lv_obj_clean_style_list(obj, LV_CALENDAR_PART_DATE);
|
||||
lv_obj_clean_style_list(obj, LV_CALENDAR_PART_HEADER);
|
||||
lv_obj_clean_style_list(obj, LV_CALENDAR_PART_DAY_NAMES);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_CPICKER
|
||||
case LV_THEME_CPICKER:
|
||||
lv_obj_clean_style_list(obj, LV_CPICKER_PART_MAIN);
|
||||
lv_obj_clean_style_list(obj, LV_CPICKER_PART_KNOB);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TEXTAREA_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINEMETER
|
||||
case LV_THEME_LINEMETER:
|
||||
lv_obj_clean_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_LINEMETER_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_GAUGE
|
||||
case LV_THEME_GAUGE:
|
||||
lv_obj_clean_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
lv_obj_clean_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
lv_obj_clean_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_GAUGE_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_GAUGE_PART_MAJOR);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_GAUGE_PART_NEEDLE);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
@@ -47,9 +47,6 @@ typedef enum {
|
||||
#if LV_USE_BTNMATRIX
|
||||
LV_THEME_BTNMATRIX,
|
||||
#endif
|
||||
#if LV_USE_CALENDAR
|
||||
LV_THEME_CALENDAR,
|
||||
#endif
|
||||
#if LV_USE_CANVAS
|
||||
LV_THEME_CANVAS,
|
||||
#endif
|
||||
@@ -59,12 +56,6 @@ typedef enum {
|
||||
#if LV_USE_CHART
|
||||
LV_THEME_CHART,
|
||||
#endif
|
||||
#if LV_USE_CONT
|
||||
LV_THEME_CONT,
|
||||
#endif
|
||||
#if LV_USE_CPICKER
|
||||
LV_THEME_CPICKER,
|
||||
#endif
|
||||
#if LV_USE_DROPDOWN
|
||||
LV_THEME_DROPDOWN,
|
||||
#endif
|
||||
@@ -77,9 +68,6 @@ typedef enum {
|
||||
#if LV_USE_IMGBTN
|
||||
LV_THEME_IMGBTN,
|
||||
#endif
|
||||
#if LV_USE_KEYBOARD
|
||||
LV_THEME_KEYBOARD,
|
||||
#endif
|
||||
#if LV_USE_LABEL
|
||||
LV_THEME_LABEL,
|
||||
#endif
|
||||
@@ -89,56 +77,27 @@ typedef enum {
|
||||
#if LV_USE_LINE
|
||||
LV_THEME_LINE,
|
||||
#endif
|
||||
#if LV_USE_LIST
|
||||
LV_THEME_LIST,
|
||||
LV_THEME_LIST_BTN,
|
||||
#endif
|
||||
#if LV_USE_LINEMETER
|
||||
LV_THEME_LINEMETER,
|
||||
#endif
|
||||
#if LV_USE_MSGBOX
|
||||
LV_THEME_MSGBOX,
|
||||
LV_THEME_MSGBOX_BTNS, /*The button matrix of the buttons are initialized separately*/
|
||||
#endif
|
||||
#if LV_USE_OBJMASK
|
||||
LV_THEME_OBJMASK,
|
||||
#endif
|
||||
#if LV_USE_PAGE
|
||||
LV_THEME_PAGE,
|
||||
#endif
|
||||
#if LV_USE_ROLLER
|
||||
LV_THEME_ROLLER,
|
||||
#endif
|
||||
#if LV_USE_SLIDER
|
||||
LV_THEME_SLIDER,
|
||||
#endif
|
||||
#if LV_USE_SPINBOX
|
||||
LV_THEME_SPINBOX,
|
||||
LV_THEME_SPINBOX_BTN, /*Control button for the spinbox*/
|
||||
#endif
|
||||
#if LV_USE_SPINNER
|
||||
LV_THEME_SPINNER,
|
||||
#endif
|
||||
#if LV_USE_SWITCH
|
||||
LV_THEME_SWITCH,
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
LV_THEME_TABLE,
|
||||
#endif
|
||||
#if LV_USE_TABVIEW
|
||||
LV_THEME_TABVIEW,
|
||||
LV_THEME_TABVIEW_PAGE, /*The tab pages are initialized separately*/
|
||||
#endif
|
||||
#if LV_USE_TEXTAREA
|
||||
LV_THEME_TEXTAREA,
|
||||
#endif
|
||||
#if LV_USE_TILEVIEW
|
||||
LV_THEME_TILEVIEW,
|
||||
#endif
|
||||
#if LV_USE_WIN
|
||||
LV_THEME_WIN,
|
||||
LV_THEME_WIN_BTN, /*The buttons are initialized separately*/
|
||||
#endif
|
||||
|
||||
_LV_THEME_BUILTIN_LAST,
|
||||
LV_THEME_CUSTOM_START = _LV_THEME_BUILTIN_LAST,
|
||||
|
||||
@@ -99,7 +99,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
{
|
||||
LV_UNUSED(th);
|
||||
if(name == LV_THEME_SCR) {
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_obj_reset_style_list_no_refr(obj, LV_OBJ_PART_MAIN);
|
||||
lv_obj_add_style(obj, LV_OBJ_PART_MAIN, &styles->opa_cover);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
|
||||
#define COLOR_BG_BORDER (IS_LIGHT ? lv_color_hex(0xd6dde3) : lv_color_hex(0x808a97)) /*dfe7ed*/
|
||||
#define COLOR_BG_BORDER_PR (IS_LIGHT ? lv_color_hex3(0xccc) : lv_color_hex(0x5f656e))
|
||||
#define COLOR_BG_BORDER_CHK (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
|
||||
#define COLOR_BG_BORDER_CHK_PR (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0x5f656e))
|
||||
#define COLOR_BG_BORDER_CHK (IS_LIGHT ? lv_color_hex(0xd6dde3) : lv_color_hex(0x5f656e))
|
||||
#define COLOR_BG_BORDER_CHK_PR (IS_LIGHT ? lv_color_hex3(0xccc) : lv_color_hex(0x5f656e))
|
||||
#define COLOR_BG_BORDER_DIS (IS_LIGHT ? lv_color_hex(0xd6dde3) : lv_color_hex(0x5f656e))
|
||||
|
||||
#define COLOR_BG_TEXT (IS_LIGHT ? lv_color_hex(0x3b3e42) : lv_color_hex(0xffffff))
|
||||
@@ -64,7 +64,7 @@
|
||||
#define COLOR_BG_SEC_TEXT (IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xa5a8ad))
|
||||
#define COLOR_BG_SEC_TEXT_DIS (IS_LIGHT ? lv_color_hex(0xaaaaaa) : lv_color_hex(0xa5a8ad))
|
||||
|
||||
#define TRANSITION_TIME 0/*((theme.flags & LV_THEME_MATERIAL_FLAG_NO_TRANSITION) ? 0 : 150)*/
|
||||
#define TRANSITION_TIME ((theme.flags & LV_THEME_MATERIAL_FLAG_NO_TRANSITION) ? 0 : 150)
|
||||
#define BORDER_WIDTH LV_DPX(2)
|
||||
#define OUTLINE_WIDTH ((theme.flags & LV_THEME_MATERIAL_FLAG_NO_FOCUS) ? 0 : LV_DPX(2))
|
||||
#define IS_LIGHT (theme.flags & LV_THEME_MATERIAL_FLAG_LIGHT)
|
||||
@@ -76,11 +76,11 @@
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_style_t scr;
|
||||
lv_style_t sb;
|
||||
lv_style_t bg;
|
||||
lv_style_t bg_click;
|
||||
lv_style_t bg_sec;
|
||||
lv_style_t btn;
|
||||
lv_style_t pad_inner;
|
||||
lv_style_t pad_small;
|
||||
|
||||
#if LV_USE_ARC
|
||||
@@ -94,12 +94,8 @@ typedef struct {
|
||||
lv_style_t bar_indic;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
lv_style_t calendar_date_nums, calendar_header, calendar_daynames;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CPICKER
|
||||
lv_style_t cpicker_bg, cpicker_indic;
|
||||
#if LV_USE_BTNMATRIX
|
||||
lv_style_t btnmatrix_btn;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
@@ -118,33 +114,10 @@ typedef struct {
|
||||
lv_style_t gauge_main, gauge_strong, gauge_needle;
|
||||
#endif
|
||||
|
||||
#if LV_USE_KEYBOARD
|
||||
lv_style_t kb_bg;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LED
|
||||
lv_style_t led;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINEMETER
|
||||
lv_style_t lmeter;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIST
|
||||
lv_style_t list_bg, list_btn;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MSGBOX
|
||||
lv_style_t mbox_bg;
|
||||
#endif
|
||||
|
||||
#if LV_USE_PAGE
|
||||
lv_style_t sb;
|
||||
#if LV_USE_ANIMATION
|
||||
lv_style_t edge_flash;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
lv_style_t roller_bg, roller_sel;
|
||||
#endif
|
||||
@@ -153,10 +126,6 @@ typedef struct {
|
||||
lv_style_t slider_knob, slider_bg;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPINBOX
|
||||
lv_style_t spinbox_cursor;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
lv_style_t sw_knob;
|
||||
#endif
|
||||
@@ -165,10 +134,6 @@ typedef struct {
|
||||
lv_style_t table_cell;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TABVIEW || LV_USE_WIN
|
||||
lv_style_t tabview_btns, tabview_btns_bg, tabview_indic, tabview_page_scrl;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA
|
||||
lv_style_t ta_cursor, ta_placeholder;
|
||||
#endif
|
||||
@@ -199,6 +164,14 @@ static bool inited;
|
||||
|
||||
static void basic_init(void)
|
||||
{
|
||||
style_init_reset(&styles->sb);
|
||||
lv_style_set_scrollbar_bg_opa(&styles->sb, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_scrollbar_bg_color(&styles->sb, LV_STATE_DEFAULT, (IS_LIGHT ? lv_color_hex(0xcccfd1) : lv_color_hex(0x777f85)));
|
||||
lv_style_set_scrollbar_radius(&styles->sb, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_scrollbar_tickness(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_scrollbar_space_side(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_scrollbar_space_end(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
|
||||
style_init_reset(&styles->scr);
|
||||
lv_style_set_bg_opa(&styles->scr, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->scr, LV_STATE_DEFAULT, COLOR_SCR);
|
||||
@@ -224,11 +197,11 @@ static void basic_init(void)
|
||||
lv_style_set_image_recolor(&styles->bg, LV_STATE_DEFAULT, COLOR_BG_TEXT);
|
||||
lv_style_set_line_color(&styles->bg, LV_STATE_DEFAULT, COLOR_BG_TEXT);
|
||||
lv_style_set_line_width(&styles->bg, LV_STATE_DEFAULT, 1);
|
||||
|
||||
lv_style_set_pad_left(&styles->bg, LV_STATE_DEFAULT, PAD_DEF + BORDER_WIDTH);
|
||||
lv_style_set_pad_right(&styles->bg, LV_STATE_DEFAULT, PAD_DEF + BORDER_WIDTH);
|
||||
lv_style_set_pad_top(&styles->bg, LV_STATE_DEFAULT, PAD_DEF + BORDER_WIDTH);
|
||||
lv_style_set_pad_bottom(&styles->bg, LV_STATE_DEFAULT, PAD_DEF + BORDER_WIDTH);
|
||||
lv_style_set_pad_inner(&styles->bg, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_transition_time(&styles->bg, LV_STATE_DEFAULT, TRANSITION_TIME);
|
||||
lv_style_set_transition_prop_6(&styles->bg, LV_STATE_DEFAULT, LV_STYLE_BORDER_COLOR);
|
||||
|
||||
@@ -300,7 +273,6 @@ static void basic_init(void)
|
||||
lv_style_set_pad_right(&styles->btn, LV_STATE_DEFAULT, LV_DPX(40));
|
||||
lv_style_set_pad_top(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_pad_bottom(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_pad_inner(&styles->btn, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_outline_width(&styles->btn, LV_STATE_DEFAULT, OUTLINE_WIDTH);
|
||||
lv_style_set_outline_opa(&styles->btn, LV_STATE_DEFAULT, LV_OPA_0);
|
||||
lv_style_set_outline_opa(&styles->btn, LV_STATE_FOCUSED, LV_OPA_50);
|
||||
@@ -313,26 +285,14 @@ static void basic_init(void)
|
||||
lv_style_set_transition_delay(&styles->btn, LV_STATE_DEFAULT, TRANSITION_TIME);
|
||||
lv_style_set_transition_delay(&styles->btn, LV_STATE_PRESSED, 0);
|
||||
|
||||
style_init_reset(&styles->pad_inner);
|
||||
|
||||
lv_style_set_pad_inner(&styles->pad_inner, LV_STATE_DEFAULT,
|
||||
lv_disp_get_size_category(NULL) <= LV_DISP_MEDIUM_LIMIT ? LV_DPX(20) : LV_DPX(40));
|
||||
|
||||
style_init_reset(&styles->pad_small);
|
||||
lv_style_int_t pad_small_value = lv_disp_get_size_category(NULL) <= LV_DISP_MEDIUM_LIMIT ? LV_DPX(10) : LV_DPX(20);
|
||||
lv_style_set_pad_left(&styles->pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_right(&styles->pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_top(&styles->pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_bottom(&styles->pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_inner(&styles->pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
}
|
||||
|
||||
static void cont_init(void)
|
||||
{
|
||||
#if LV_USE_CONT != 0
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void btn_init(void)
|
||||
{
|
||||
@@ -341,6 +301,14 @@ static void btn_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void btnmatrix_init(void)
|
||||
{
|
||||
#if LV_USE_BTNMATRIX != 0
|
||||
style_init_reset(&styles->btnmatrix_btn);
|
||||
lv_style_set_margin_all(&styles->btnmatrix_btn, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void label_init(void)
|
||||
{
|
||||
#if LV_USE_LABEL != 0
|
||||
@@ -387,22 +355,6 @@ static void line_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void led_init(void)
|
||||
{
|
||||
#if LV_USE_LED != 0
|
||||
style_init_reset(&styles->led);
|
||||
lv_style_set_bg_opa(&styles->led, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->led, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_border_width(&styles->led, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_border_opa(&styles->led, LV_STATE_DEFAULT, LV_OPA_50);
|
||||
lv_style_set_border_color(&styles->led, LV_STATE_DEFAULT, lv_color_lighten(theme.color_primary, LV_OPA_30));
|
||||
lv_style_set_radius(&styles->led, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_shadow_width(&styles->led, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_shadow_color(&styles->led, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_shadow_spread(&styles->led, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void slider_init(void)
|
||||
{
|
||||
#if LV_USE_SLIDER != 0
|
||||
@@ -447,7 +399,6 @@ static void linemeter_init(void)
|
||||
lv_style_set_pad_left(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_right(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_top(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_inner(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(30));
|
||||
lv_style_set_scale_width(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
|
||||
lv_style_set_line_color(&styles->lmeter, LV_STATE_DEFAULT, theme.color_primary);
|
||||
@@ -471,7 +422,7 @@ static void gauge_init(void)
|
||||
lv_style_set_pad_left(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_right(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_top(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_inner(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_all(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_scale_width(&styles->gauge_main, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_radius(&styles->gauge_main, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
@@ -490,7 +441,7 @@ static void gauge_init(void)
|
||||
lv_style_set_bg_color(&styles->gauge_needle, LV_STATE_DEFAULT, IS_LIGHT ? lv_color_hex(0x464b5b) : LV_COLOR_WHITE);
|
||||
lv_style_set_radius(&styles->gauge_needle, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_size(&styles->gauge_needle, LV_STATE_DEFAULT, LV_DPX(30));
|
||||
lv_style_set_pad_inner(&styles->gauge_needle, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_pad_all(&styles->gauge_needle, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -538,91 +489,22 @@ static void chart_init(void)
|
||||
style_init_reset(&styles->chart_series);
|
||||
lv_style_set_line_width(&styles->chart_series, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
lv_style_set_size(&styles->chart_series, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_pad_inner(&styles->chart_series, LV_STATE_DEFAULT, LV_DPX(2)); /*Space between columns*/
|
||||
lv_style_set_pad_all(&styles->chart_series, LV_STATE_DEFAULT, LV_DPX(2)); /*Space between columns*/
|
||||
lv_style_set_radius(&styles->chart_series, LV_STATE_DEFAULT, LV_DPX(1));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void calendar_init(void)
|
||||
{
|
||||
#if LV_USE_CALENDAR
|
||||
|
||||
style_init_reset(&styles->calendar_header);
|
||||
lv_style_set_pad_top(&styles->calendar_header, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_left(&styles->calendar_header, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_right(&styles->calendar_header, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_bottom(&styles->calendar_header, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_margin_top(&styles->calendar_header, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_margin_bottom(&styles->calendar_header, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_text_color(&styles->calendar_header, LV_STATE_PRESSED, IS_LIGHT ? lv_color_hex(0x888888) : LV_COLOR_WHITE);
|
||||
|
||||
style_init_reset(&styles->calendar_daynames);
|
||||
lv_style_set_text_color(&styles->calendar_daynames, LV_STATE_DEFAULT,
|
||||
IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex3(0xeee));
|
||||
lv_style_set_pad_left(&styles->calendar_daynames, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_right(&styles->calendar_daynames, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_bottom(&styles->calendar_daynames, LV_STATE_DEFAULT, PAD_DEF);
|
||||
|
||||
style_init_reset(&styles->calendar_date_nums);
|
||||
lv_style_set_radius(&styles->calendar_date_nums, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_text_color(&styles->calendar_date_nums, LV_STATE_CHECKED,
|
||||
IS_LIGHT ? lv_color_hex(0x31404f) : LV_COLOR_WHITE);
|
||||
lv_style_set_text_color(&styles->calendar_date_nums, LV_STATE_DISABLED, LV_COLOR_GRAY);
|
||||
lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_CHECKED, IS_LIGHT ? LV_OPA_20 : LV_OPA_40);
|
||||
lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_PRESSED, LV_OPA_20);
|
||||
lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_FOCUSED, LV_OPA_COVER);
|
||||
lv_style_set_text_color(&styles->calendar_date_nums, LV_STATE_FOCUSED, LV_COLOR_WHITE);
|
||||
lv_style_set_bg_color(&styles->calendar_date_nums, LV_STATE_FOCUSED, theme.color_primary);
|
||||
lv_style_set_bg_color(&styles->calendar_date_nums, LV_STATE_DEFAULT,
|
||||
IS_LIGHT ? lv_color_hex(0x666666) : LV_COLOR_WHITE);
|
||||
lv_style_set_bg_color(&styles->calendar_date_nums, LV_STATE_CHECKED, theme.color_primary);
|
||||
lv_style_set_border_width(&styles->calendar_date_nums, LV_STATE_CHECKED, 2);
|
||||
lv_style_set_border_side(&styles->calendar_date_nums, LV_STATE_CHECKED, LV_BORDER_SIDE_LEFT);
|
||||
lv_style_set_border_color(&styles->calendar_date_nums, LV_STATE_CHECKED, theme.color_primary);
|
||||
lv_style_set_pad_inner(&styles->calendar_date_nums, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
lv_style_set_pad_left(&styles->calendar_date_nums, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_right(&styles->calendar_date_nums, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_bottom(&styles->calendar_date_nums, LV_STATE_DEFAULT, PAD_DEF);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cpicker_init(void)
|
||||
{
|
||||
#if LV_USE_CPICKER
|
||||
style_init_reset(&styles->cpicker_bg);
|
||||
lv_style_set_scale_width(&styles->cpicker_bg, LV_STATE_DEFAULT, LV_DPX(30));
|
||||
lv_style_set_bg_opa(&styles->cpicker_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->cpicker_bg, LV_STATE_DEFAULT, COLOR_SCR);
|
||||
lv_style_set_pad_inner(&styles->cpicker_bg, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_radius(&styles->cpicker_bg, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
style_init_reset(&styles->cpicker_indic);
|
||||
lv_style_set_radius(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_bg_color(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_bg_opa(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_border_width(&styles->cpicker_indic, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_border_color(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||
lv_style_set_border_color(&styles->cpicker_indic, LV_STATE_FOCUSED, theme.color_primary);
|
||||
lv_style_set_border_color(&styles->cpicker_indic, LV_STATE_EDITED, theme.color_secondary);
|
||||
lv_style_set_pad_left(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_DPX(13));
|
||||
lv_style_set_pad_right(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_DPX(13));
|
||||
lv_style_set_pad_top(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_DPX(13));
|
||||
lv_style_set_pad_bottom(&styles->cpicker_indic, LV_STATE_DEFAULT, LV_DPX(13));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void checkbox_init(void)
|
||||
{
|
||||
#if LV_USE_CHECKBOX != 0
|
||||
style_init_reset(&styles->cb_bg);
|
||||
lv_style_set_radius(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_pad_inner(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_outline_color(&styles->cb_bg, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_FOCUSED, LV_OPA_50);
|
||||
lv_style_set_outline_width(&styles->cb_bg, LV_STATE_DEFAULT, OUTLINE_WIDTH);
|
||||
lv_style_set_outline_pad(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_outline_pad(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(6));
|
||||
lv_style_set_transition_time(&styles->cb_bg, LV_STATE_DEFAULT, TRANSITION_TIME);
|
||||
lv_style_set_transition_prop_6(&styles->cb_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA);
|
||||
|
||||
@@ -639,56 +521,7 @@ static void checkbox_init(void)
|
||||
lv_style_set_pad_right(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
lv_style_set_pad_top(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
lv_style_set_pad_bottom(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void btnmatrix_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void keyboard_init(void)
|
||||
{
|
||||
#if LV_USE_KEYBOARD
|
||||
style_init_reset(&styles->kb_bg);
|
||||
lv_style_set_radius(&styles->kb_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_border_width(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_border_side(&styles->kb_bg, LV_STATE_DEFAULT, LV_BORDER_SIDE_TOP);
|
||||
lv_style_set_border_color(&styles->kb_bg, LV_STATE_DEFAULT, IS_LIGHT ? COLOR_BG_TEXT : LV_COLOR_BLACK);
|
||||
lv_style_set_border_color(&styles->kb_bg, LV_STATE_EDITED, theme.color_secondary);
|
||||
lv_style_set_pad_left(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_pad_right(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_pad_top(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_pad_bottom(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_pad_inner(&styles->kb_bg, LV_STATE_DEFAULT, LV_DPX(3));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void msgbox_init(void)
|
||||
{
|
||||
#if LV_USE_MSGBOX
|
||||
style_init_reset(&styles->mbox_bg);
|
||||
lv_style_set_shadow_width(&styles->mbox_bg, LV_STATE_DEFAULT, LV_DPX(50));
|
||||
lv_style_set_shadow_color(&styles->mbox_bg, LV_STATE_DEFAULT, IS_LIGHT ? LV_COLOR_SILVER : lv_color_hex3(0x999));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void page_init(void)
|
||||
{
|
||||
#if LV_USE_PAGE
|
||||
style_init_reset(&styles->sb);
|
||||
lv_style_set_bg_opa(&styles->sb, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->sb, LV_STATE_DEFAULT, (IS_LIGHT ? lv_color_hex(0xcccfd1) : lv_color_hex(0x777f85)));
|
||||
lv_style_set_radius(&styles->sb, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_size(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_pad_right(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_pad_bottom(&styles->sb, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
style_init_reset(&styles->edge_flash);
|
||||
lv_style_set_bg_opa(&styles->edge_flash, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->edge_flash, LV_STATE_DEFAULT, lv_color_hex3(0x888));
|
||||
#endif
|
||||
lv_style_set_margin_right(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(6));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -707,74 +540,6 @@ static void textarea_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void spinbox_init(void)
|
||||
{
|
||||
#if LV_USE_SPINBOX
|
||||
|
||||
style_init_reset(&styles->spinbox_cursor);
|
||||
lv_style_set_bg_opa(&styles->spinbox_cursor, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->spinbox_cursor, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_text_color(&styles->spinbox_cursor, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_pad_top(&styles->spinbox_cursor, LV_STATE_DEFAULT, LV_DPX(100));
|
||||
lv_style_set_pad_bottom(&styles->spinbox_cursor, LV_STATE_DEFAULT, LV_DPX(100));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void list_init(void)
|
||||
{
|
||||
#if LV_USE_LIST != 0
|
||||
style_init_reset(&styles->list_bg);
|
||||
lv_style_set_clip_corner(&styles->list_bg, LV_STATE_DEFAULT, true);
|
||||
lv_style_set_pad_left(&styles->list_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_right(&styles->list_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_top(&styles->list_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_bottom(&styles->list_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_inner(&styles->list_bg, LV_STATE_DEFAULT, 0);
|
||||
|
||||
style_init_reset(&styles->list_btn);
|
||||
lv_style_set_bg_opa(&styles->list_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->list_btn, LV_STATE_DEFAULT, COLOR_BG);
|
||||
lv_style_set_bg_color(&styles->list_btn, LV_STATE_PRESSED, COLOR_BG_PR);
|
||||
lv_style_set_bg_color(&styles->list_btn, LV_STATE_DISABLED, COLOR_BG_DIS);
|
||||
lv_style_set_bg_color(&styles->list_btn, LV_STATE_CHECKED, COLOR_BG_CHK);
|
||||
lv_style_set_bg_color(&styles->list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, COLOR_BG_PR_CHK);
|
||||
|
||||
lv_style_set_text_color(&styles->list_btn, LV_STATE_DEFAULT, COLOR_BG_TEXT);
|
||||
lv_style_set_text_color(&styles->list_btn, LV_STATE_CHECKED, COLOR_BG_TEXT_CHK);
|
||||
lv_style_set_text_color(&styles->list_btn, LV_STATE_DISABLED, COLOR_BG_TEXT_DIS);
|
||||
|
||||
lv_style_set_image_recolor(&styles->list_btn, LV_STATE_DEFAULT, COLOR_BG_TEXT);
|
||||
lv_style_set_image_recolor(&styles->list_btn, LV_STATE_CHECKED, COLOR_BG_TEXT_CHK);
|
||||
lv_style_set_image_recolor(&styles->list_btn, LV_STATE_DISABLED, COLOR_BG_TEXT_DIS);
|
||||
|
||||
lv_style_set_border_side(&styles->list_btn, LV_STATE_DEFAULT, LV_BORDER_SIDE_BOTTOM);
|
||||
lv_style_set_border_color(&styles->list_btn, LV_STATE_DEFAULT, COLOR_BG_BORDER);
|
||||
lv_style_set_border_color(&styles->list_btn, LV_STATE_FOCUSED, theme.color_primary);
|
||||
lv_style_set_border_width(&styles->list_btn, LV_STATE_DEFAULT, 1);
|
||||
|
||||
lv_style_set_outline_color(&styles->list_btn, LV_STATE_FOCUSED, theme.color_secondary);
|
||||
lv_style_set_outline_width(&styles->list_btn, LV_STATE_FOCUSED, OUTLINE_WIDTH);
|
||||
lv_style_set_outline_pad(&styles->list_btn, LV_STATE_FOCUSED, -BORDER_WIDTH);
|
||||
|
||||
lv_style_set_pad_left(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_right(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_top(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_bottom(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_inner(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);
|
||||
|
||||
lv_style_set_transform_width(&styles->list_btn, LV_STATE_DEFAULT, - PAD_DEF);
|
||||
lv_style_set_transform_width(&styles->list_btn, LV_STATE_PRESSED, -BORDER_WIDTH);
|
||||
lv_style_set_transform_width(&styles->list_btn, LV_STATE_CHECKED, -BORDER_WIDTH);
|
||||
lv_style_set_transform_width(&styles->list_btn, LV_STATE_DISABLED, -BORDER_WIDTH);
|
||||
lv_style_set_transform_width(&styles->list_btn, LV_STATE_FOCUSED, - BORDER_WIDTH);
|
||||
|
||||
lv_style_set_transition_time(&styles->list_btn, LV_STATE_DEFAULT, TRANSITION_TIME);
|
||||
lv_style_set_transition_prop_6(&styles->list_btn, LV_STATE_DEFAULT, LV_STYLE_BG_COLOR);
|
||||
lv_style_set_transition_prop_5(&styles->list_btn, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_WIDTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ddlist_init(void)
|
||||
{
|
||||
#if LV_USE_DROPDOWN != 0
|
||||
@@ -838,44 +603,6 @@ static void win_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tabview_win_shared_init(void)
|
||||
{
|
||||
#if LV_USE_TABVIEW || LV_USE_WIN
|
||||
style_init_reset(&styles->tabview_btns_bg);
|
||||
lv_style_set_bg_opa(&styles->tabview_btns_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->tabview_btns_bg, LV_STATE_DEFAULT, COLOR_BG);
|
||||
lv_style_set_text_color(&styles->tabview_btns_bg, LV_STATE_DEFAULT, COLOR_SCR_TEXT);
|
||||
lv_style_set_image_recolor(&styles->tabview_btns_bg, LV_STATE_DEFAULT, lv_color_hex(0x979a9f));
|
||||
lv_style_set_pad_top(&styles->tabview_btns_bg, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_pad_left(&styles->tabview_btns_bg, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
lv_style_set_pad_right(&styles->tabview_btns_bg, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
|
||||
style_init_reset(&styles->tabview_btns);
|
||||
lv_style_set_bg_opa(&styles->tabview_btns, LV_STATE_PRESSED, LV_OPA_50);
|
||||
lv_style_set_bg_color(&styles->tabview_btns, LV_STATE_PRESSED, lv_color_hex3(0x888));
|
||||
lv_style_set_text_color(&styles->tabview_btns, LV_STATE_CHECKED, COLOR_SCR_TEXT);
|
||||
lv_style_set_pad_top(&styles->tabview_btns, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_bottom(&styles->tabview_btns, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_text_color(&styles->tabview_btns, LV_STATE_FOCUSED, theme.color_primary);
|
||||
lv_style_set_text_color(&styles->tabview_btns, LV_STATE_EDITED, theme.color_secondary);
|
||||
|
||||
style_init_reset(&styles->tabview_indic);
|
||||
lv_style_set_bg_opa(&styles->tabview_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->tabview_indic, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_bg_color(&styles->tabview_indic, LV_STATE_EDITED, theme.color_secondary);
|
||||
lv_style_set_size(&styles->tabview_indic, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_radius(&styles->tabview_indic, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
style_init_reset(&styles->tabview_page_scrl);
|
||||
lv_style_set_pad_top(&styles->tabview_page_scrl, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_bottom(&styles->tabview_page_scrl, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_left(&styles->tabview_page_scrl, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_right(&styles->tabview_page_scrl, LV_STATE_DEFAULT, PAD_DEF);
|
||||
lv_style_set_pad_inner(&styles->tabview_page_scrl, LV_STATE_DEFAULT, PAD_DEF);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
@@ -913,13 +640,12 @@ lv_theme_t * lv_theme_material_init(lv_color_t color_primary, lv_color_t color_s
|
||||
theme.flags = flags;
|
||||
|
||||
basic_init();
|
||||
cont_init();
|
||||
btn_init();
|
||||
btnmatrix_init();
|
||||
label_init();
|
||||
bar_init();
|
||||
img_init();
|
||||
line_init();
|
||||
led_init();
|
||||
slider_init();
|
||||
switch_init();
|
||||
linemeter_init();
|
||||
@@ -927,30 +653,22 @@ lv_theme_t * lv_theme_material_init(lv_color_t color_primary, lv_color_t color_s
|
||||
arc_init();
|
||||
spinner_init();
|
||||
chart_init();
|
||||
calendar_init();
|
||||
cpicker_init();
|
||||
checkbox_init();
|
||||
btnmatrix_init();
|
||||
keyboard_init();
|
||||
msgbox_init();
|
||||
page_init();
|
||||
textarea_init();
|
||||
spinbox_init();
|
||||
list_init();
|
||||
ddlist_init();
|
||||
roller_init();
|
||||
tabview_init();
|
||||
tileview_init();
|
||||
table_init();
|
||||
win_init();
|
||||
tabview_win_shared_init();
|
||||
|
||||
theme.apply_xcb = NULL;
|
||||
theme.apply_cb = theme_apply;
|
||||
|
||||
inited = true;
|
||||
|
||||
lv_obj_report_style_mod(NULL);
|
||||
lv_obj_report_style_change(NULL);
|
||||
|
||||
return &theme;
|
||||
}
|
||||
@@ -967,79 +685,64 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
|
||||
case LV_THEME_SCR:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
case LV_THEME_OBJ:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
#if LV_USE_CONT
|
||||
case LV_THEME_CONT:
|
||||
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTN
|
||||
case LV_THEME_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTNMATRIX
|
||||
case LV_THEME_BTNMATRIX:
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->bg_click);
|
||||
break;
|
||||
#endif
|
||||
_lv_style_list_add_style(list, &styles->btnmatrix_btn);
|
||||
|
||||
#if LV_USE_KEYBOARD
|
||||
case LV_THEME_KEYBOARD:
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
_lv_style_list_add_style(list, &styles->kb_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BTN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN_2);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->bg_click);
|
||||
_lv_style_list_add_style(list, &styles->btnmatrix_btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BAR
|
||||
case LV_THEME_BAR:
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bar_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bar_indic);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
case LV_THEME_SWITCH:
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bar_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bar_indic);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->sw_knob);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CANVAS
|
||||
case LV_THEME_CANVAS:
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMG
|
||||
case LV_THEME_IMAGE:
|
||||
break;
|
||||
@@ -1062,206 +765,103 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_ARC
|
||||
case LV_THEME_ARC:
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->arc_bg);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->arc_indic);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->bg_click);
|
||||
_lv_style_list_add_style(list, &styles->arc_knob);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPINNER
|
||||
case LV_THEME_SPINNER:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->arc_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->arc_indic);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
case LV_THEME_SLIDER:
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bar_bg);
|
||||
_lv_style_list_add_style(list, &styles->slider_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bar_indic);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->slider_knob);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
case LV_THEME_CHECKBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->cb_bg);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->cb_bullet);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MSGBOX
|
||||
case LV_THEME_MSGBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->mbox_bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_MSGBOX_BTNS:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN_BG);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if LV_USE_LED
|
||||
case LV_THEME_LED:
|
||||
list = lv_obj_get_style_list(obj, LV_LED_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->led);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_PAGE
|
||||
case LV_THEME_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->pad_inner);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_EDGE_FLASH);
|
||||
_lv_style_list_add_style(list, &styles->edge_flash);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABVIEW
|
||||
case LV_THEME_TABVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BG);
|
||||
_lv_style_list_add_style(list, &styles->tabview_btns_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->tabview_indic);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BTN);
|
||||
_lv_style_list_add_style(list, &styles->tabview_btns);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABVIEW_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->tabview_page_scrl);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TILEVIEW
|
||||
case LV_THEME_TILEVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_EDGE_FLASH);
|
||||
_lv_style_list_add_style(list, &styles->edge_flash);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
case LV_THEME_ROLLER:
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->roller_bg);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->roller_sel);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_OBJMASK
|
||||
case LV_THEME_OBJMASK:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIST
|
||||
case LV_THEME_LIST:
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->list_bg);
|
||||
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->list_btn);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DROPDOWN
|
||||
case LV_THEME_DROPDOWN:
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->bg_click);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->ddlist_page);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->ddlist_sel);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CHART
|
||||
case LV_THEME_CHART:
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->chart_bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
_lv_style_list_add_style(list, &styles->chart_series_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_CURSOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->chart_series_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
_lv_style_list_add_style(list, &styles->chart_series);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
case LV_THEME_TABLE: {
|
||||
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
int idx = 1; /* start value should be 1, not zero, since cell styles
|
||||
@@ -1269,112 +869,46 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
in the enum (lv_table.h) */
|
||||
/* declaring idx outside loop to work with older compilers */
|
||||
for(; idx <= LV_TABLE_CELL_STYLE_CNT; idx ++) {
|
||||
list = lv_obj_get_style_list(obj, idx);
|
||||
list = _lv_obj_get_style_list(obj, idx);
|
||||
_lv_style_list_add_style(list, &styles->table_cell);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_WIN
|
||||
case LV_THEME_WIN:
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_CONTENT_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->tabview_page_scrl);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->tabview_btns_bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_WIN_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->tabview_btns);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA
|
||||
case LV_THEME_TEXTAREA:
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
_lv_style_list_add_style(list, &styles->ta_placeholder);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->ta_cursor);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_SPINBOX
|
||||
case LV_THEME_SPINBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->spinbox_cursor);
|
||||
break;
|
||||
|
||||
case LV_THEME_SPINBOX_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->bg_click);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
case LV_THEME_CALENDAR:
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DATE);
|
||||
_lv_style_list_add_style(list, &styles->calendar_date_nums);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->calendar_header);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DAY_NAMES);
|
||||
_lv_style_list_add_style(list, &styles->calendar_daynames);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_CPICKER
|
||||
case LV_THEME_CPICKER:
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->cpicker_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->cpicker_indic);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINEMETER
|
||||
case LV_THEME_LINEMETER:
|
||||
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->lmeter);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_GAUGE
|
||||
case LV_THEME_GAUGE:
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->gauge_main);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
_lv_style_list_add_style(list, &styles->gauge_strong);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
_lv_style_list_add_style(list, &styles->gauge_needle);
|
||||
break;
|
||||
#endif
|
||||
@@ -1382,7 +916,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
}
|
||||
|
||||
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -37,7 +37,6 @@ typedef struct {
|
||||
lv_style_t pad_none;
|
||||
lv_style_t pad_normal;
|
||||
lv_style_t pad_small;
|
||||
lv_style_t pad_inner;
|
||||
lv_style_t txt_underline;
|
||||
|
||||
#if LV_USE_ARC
|
||||
@@ -139,7 +138,6 @@ static void basic_init(void)
|
||||
lv_style_set_pad_right(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_top(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_bottom(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_inner(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
|
||||
style_init_reset(&styles->clip_corner);
|
||||
lv_style_set_clip_corner(&styles->clip_corner, LV_STATE_DEFAULT, true);
|
||||
@@ -192,24 +190,18 @@ static void basic_init(void)
|
||||
lv_style_set_pad_right(&styles->pad_none, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_top(&styles->pad_none, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_bottom(&styles->pad_none, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_inner(&styles->pad_none, LV_STATE_DEFAULT, 0);
|
||||
|
||||
style_init_reset(&styles->pad_normal);
|
||||
lv_style_set_pad_left(&styles->pad_normal, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_right(&styles->pad_normal, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_top(&styles->pad_normal, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_bottom(&styles->pad_normal, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_inner(&styles->pad_normal, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
|
||||
style_init_reset(&styles->pad_small);
|
||||
lv_style_set_pad_left(&styles->pad_small, LV_STATE_DEFAULT, LV_DPI / 20);
|
||||
lv_style_set_pad_right(&styles->pad_small, LV_STATE_DEFAULT, LV_DPI / 20);
|
||||
lv_style_set_pad_top(&styles->pad_small, LV_STATE_DEFAULT, LV_DPI / 20);
|
||||
lv_style_set_pad_bottom(&styles->pad_small, LV_STATE_DEFAULT, LV_DPI / 20);
|
||||
lv_style_set_pad_inner(&styles->pad_small, LV_STATE_DEFAULT, LV_DPI / 20);
|
||||
|
||||
style_init_reset(&styles->pad_inner);
|
||||
lv_style_set_pad_inner(&styles->pad_inner, LV_STATE_DEFAULT, LV_DPI / 15);
|
||||
|
||||
style_init_reset(&styles->txt_underline);
|
||||
lv_style_set_text_decor(&styles->txt_underline, LV_STATE_FOCUSED, LV_TEXT_DECOR_UNDERLINE);
|
||||
@@ -383,13 +375,7 @@ static void slider_init(void)
|
||||
static void switch_init(void)
|
||||
{
|
||||
#if LV_USE_SWITCH != 0
|
||||
style_init_reset(&styles->sb);
|
||||
lv_style_set_bg_opa(&styles->sb, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&styles->sb, LV_STATE_DEFAULT, FG_COLOR);
|
||||
lv_style_set_radius(&styles->sb, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_pad_right(&styles->sb, LV_STATE_DEFAULT, LV_DPI / 30);
|
||||
lv_style_set_pad_bottom(&styles->sb, LV_STATE_DEFAULT, LV_DPI / 30);
|
||||
lv_style_set_size(&styles->sb, LV_STATE_DEFAULT, LV_MATH_MAX(LV_DPI / 25, 3));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -579,23 +565,17 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
|
||||
case LV_THEME_SCR:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
break;
|
||||
case LV_THEME_OBJ:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#if LV_USE_CONT
|
||||
case LV_THEME_CONT:
|
||||
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTN
|
||||
#if LV_USE_BTN
|
||||
case LV_THEME_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
@@ -604,36 +584,24 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_BTNMATRIX
|
||||
case LV_THEME_BTNMATRIX:
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_KEYBOARD
|
||||
case LV_THEME_KEYBOARD:
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BAR
|
||||
case LV_THEME_BAR:
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
@@ -642,86 +610,67 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
case LV_THEME_SWITCH:
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CANVAS
|
||||
case LV_THEME_CANVAS:
|
||||
list = lv_obj_get_style_list(obj, LV_CANVAS_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMG
|
||||
case LV_THEME_IMAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMGBTN
|
||||
case LV_THEME_IMGBTN:
|
||||
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL
|
||||
case LV_THEME_LABEL:
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINE
|
||||
case LV_THEME_LINE:
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_ARC
|
||||
case LV_THEME_ARC:
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->arc_bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->arc_indic);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPINNER
|
||||
case LV_THEME_SPINNER:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
case LV_THEME_SLIDER:
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
@@ -731,95 +680,23 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
case LV_THEME_CHECKBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MSGBOX
|
||||
case LV_THEME_MSGBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_MSGBOX_BTNS:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN_BG);
|
||||
_lv_style_list_add_style(list, &styles->pad_inner);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if LV_USE_LED
|
||||
case LV_THEME_LED:
|
||||
list = lv_obj_get_style_list(obj, LV_LED_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_PAGE
|
||||
case LV_THEME_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->pad_inner);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABVIEW
|
||||
case LV_THEME_TABVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->scr);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BG);
|
||||
_lv_style_list_add_style(list, &styles->tab_bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABVIEW_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->pad_normal);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TILEVIEW
|
||||
case LV_THEME_TILEVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_EDGE_FLASH);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
case LV_THEME_ROLLER:
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->big_line_space);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
_lv_style_list_add_style(list, &styles->no_radius);
|
||||
@@ -829,45 +706,21 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_OBJMASK
|
||||
case LV_THEME_OBJMASK:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIST
|
||||
case LV_THEME_LIST:
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
_lv_style_list_add_style(list, &styles->clip_corner);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->list_btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DROPDOWN
|
||||
case LV_THEME_DROPDOWN:
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->big_line_space);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
_lv_style_list_add_style(list, &styles->no_radius);
|
||||
@@ -876,20 +729,20 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_CHART
|
||||
case LV_THEME_CHART:
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->border_none);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
_lv_style_list_add_style(list, &styles->chart_series);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
case LV_THEME_TABLE: {
|
||||
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
int idx = 1; /* start value should be 1, not zero, since cell styles
|
||||
@@ -897,7 +750,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
in the enum (lv_table.h) */
|
||||
/* declaring idx outside loop to work with older compilers */
|
||||
for(; idx <= LV_TABLE_CELL_STYLE_CNT; idx ++) {
|
||||
list = lv_obj_get_style_list(obj, idx);
|
||||
list = _lv_obj_get_style_list(obj, idx);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->no_radius);
|
||||
}
|
||||
@@ -905,98 +758,19 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_WIN
|
||||
case LV_THEME_WIN:
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_CONTENT_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_WIN_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA
|
||||
case LV_THEME_TEXTAREA:
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->ta_cursor);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->sb);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_SPINBOX
|
||||
case LV_THEME_SPINBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->fg_color);
|
||||
_lv_style_list_add_style(list, &styles->pad_none);
|
||||
_lv_style_list_add_style(list, &styles->no_radius);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
break;
|
||||
|
||||
case LV_THEME_SPINBOX_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->txt_underline);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
case LV_THEME_CALENDAR:
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DATE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
_lv_style_list_add_style(list, &styles->border_none);
|
||||
_lv_style_list_add_style(list, &styles->calendar_date);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->pad_normal);
|
||||
_lv_style_list_add_style(list, &styles->border_none);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DAY_NAMES);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->pad_small);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_CPICKER
|
||||
case LV_THEME_CPICKER:
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINEMETER
|
||||
case LV_THEME_LINEMETER:
|
||||
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
_lv_style_list_add_style(list, &styles->linemeter);
|
||||
@@ -1004,14 +778,14 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
#endif
|
||||
#if LV_USE_GAUGE
|
||||
case LV_THEME_GAUGE:
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
_lv_style_list_add_style(list, &styles->gauge_major);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
_lv_style_list_add_style(list, &styles->gauge_needle);
|
||||
break;
|
||||
#endif
|
||||
@@ -1020,7 +794,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
}
|
||||
|
||||
|
||||
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ static void basic_init(void)
|
||||
lv_style_set_pad_right(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_top(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_bottom(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
lv_style_set_pad_inner(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
|
||||
|
||||
style_init_reset(&styles->btn);
|
||||
lv_style_set_bg_color(&styles->btn, LV_STATE_PRESSED, lv_color_hex3(0xccc));
|
||||
@@ -107,7 +106,6 @@ static void basic_init(void)
|
||||
lv_style_set_pad_right(&styles->tight, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_top(&styles->tight, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_bottom(&styles->tight, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_pad_inner(&styles->tight, LV_STATE_DEFAULT, 0);
|
||||
}
|
||||
|
||||
static void arc_init(void)
|
||||
@@ -419,24 +417,18 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
|
||||
case LV_THEME_SCR:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
break;
|
||||
case LV_THEME_OBJ:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#if LV_USE_CONT
|
||||
case LV_THEME_CONT:
|
||||
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTN
|
||||
case LV_THEME_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
@@ -444,21 +436,10 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_BTNMATRIX
|
||||
case LV_THEME_BTNMATRIX:
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_KEYBOARD
|
||||
case LV_THEME_KEYBOARD:
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BTN);
|
||||
list = _lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
@@ -466,11 +447,11 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_BAR
|
||||
case LV_THEME_BAR:
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
break;
|
||||
@@ -478,16 +459,16 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
case LV_THEME_SWITCH:
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
@@ -496,55 +477,42 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_CANVAS
|
||||
case LV_THEME_CANVAS:
|
||||
list = lv_obj_get_style_list(obj, LV_CANVAS_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_CANVAS_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMG
|
||||
case LV_THEME_IMAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IMGBTN
|
||||
case LV_THEME_IMGBTN:
|
||||
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL
|
||||
case LV_THEME_LABEL:
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINE
|
||||
case LV_THEME_LINE:
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_ARC
|
||||
case LV_THEME_ARC:
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPINNER
|
||||
case LV_THEME_SPINNER:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
@@ -553,14 +521,14 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_SLIDER
|
||||
case LV_THEME_SLIDER:
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
list = _lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
@@ -568,103 +536,20 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_CHECKBOX
|
||||
case LV_THEME_CHECKBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_MAIN);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MSGBOX
|
||||
case LV_THEME_MSGBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_MSGBOX_BTNS:
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if LV_USE_LED
|
||||
case LV_THEME_LED:
|
||||
list = lv_obj_get_style_list(obj, LV_LED_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_PAGE
|
||||
case LV_THEME_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->gray);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABVIEW
|
||||
case LV_THEME_TABVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG_SCRLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BTN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABVIEW_PAGE:
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->gray);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TILEVIEW
|
||||
case LV_THEME_TILEVIEW:
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_EDGE_FLASH);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ROLLER
|
||||
case LV_THEME_ROLLER:
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
break;
|
||||
@@ -673,41 +558,20 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_OBJMASK
|
||||
case LV_THEME_OBJMASK:
|
||||
list = lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LIST
|
||||
case LV_THEME_LIST:
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLABLE);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
list = _lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DROPDOWN
|
||||
case LV_THEME_DROPDOWN:
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
list = _lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->color);
|
||||
break;
|
||||
@@ -715,20 +579,20 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
|
||||
#if LV_USE_CHART
|
||||
case LV_THEME_CHART:
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
list = _lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
case LV_THEME_TABLE: {
|
||||
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
int idx = 1; /* start value should be 1, not zero, since cell styles
|
||||
@@ -736,115 +600,44 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
in the enum (lv_table.h) */
|
||||
/* declaring idx outside loop to work with older compilers */
|
||||
for(; idx <= LV_TABLE_CELL_STYLE_CNT; idx ++) {
|
||||
list = lv_obj_get_style_list(obj, idx);
|
||||
list = _lv_obj_get_style_list(obj, idx);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_WIN
|
||||
case LV_THEME_WIN:
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_CONTENT_SCROLLABLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_WIN_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_WIN_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA
|
||||
case LV_THEME_TEXTAREA:
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_BG);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
|
||||
_lv_style_list_add_style(list, &styles->gray);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_SPINBOX
|
||||
case LV_THEME_SPINBOX:
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_CURSOR);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_SPINBOX_BTN:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_CALENDAR
|
||||
case LV_THEME_CALENDAR:
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_BG);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DATE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->btn);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_HEADER);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DAY_NAMES);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->tight);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_CPICKER
|
||||
case LV_THEME_CPICKER:
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LINEMETER
|
||||
case LV_THEME_LINEMETER:
|
||||
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
break;
|
||||
#endif
|
||||
#if LV_USE_GAUGE
|
||||
case LV_THEME_GAUGE:
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
_lv_style_list_add_style(list, &styles->round);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
|
||||
_lv_style_list_add_style(list, &styles->tick_line);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
list = _lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
|
||||
_lv_style_list_add_style(list, &styles->bg);
|
||||
break;
|
||||
#endif
|
||||
@@ -852,7 +645,7 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
}
|
||||
|
||||
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -104,8 +104,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new arc arc*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_click(arc, true);
|
||||
lv_obj_add_protect(arc, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_add_flag(arc, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_ext_click_area(arc, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10);
|
||||
lv_arc_set_value(arc, ext->min_value);
|
||||
lv_theme_apply(arc, LV_THEME_ARC);
|
||||
@@ -130,7 +129,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_style_list_copy(&ext->style_arc, ©_ext->style_arc);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(arc, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(arc, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("arc created");
|
||||
@@ -707,22 +706,23 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area
|
||||
static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_arc_get_style(arc, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(arc, sign, param);
|
||||
}
|
||||
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(arc, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);
|
||||
|
||||
if(sign == LV_SIGNAL_PRESSING) {
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_arc_get_style(arc, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(arc, sign, param);
|
||||
} else if(sign == LV_SIGNAL_PRESSING) {
|
||||
/* Only adjustable arcs can be dragged */
|
||||
if(!ext->adjustable) return res;
|
||||
|
||||
@@ -862,8 +862,8 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(arc, LV_ARC_PART_KNOB);
|
||||
lv_obj_clean_style_list(arc, LV_ARC_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(arc, LV_ARC_PART_KNOB);
|
||||
_lv_obj_reset_style_list_no_refr(arc, LV_ARC_PART_INDIC);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -931,7 +931,7 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl
|
||||
extra_area = rounded ? w / 2 + 2 : 0;
|
||||
|
||||
if(part == LV_ARC_PART_INDIC && lv_style_list_get_style(&ext->style_knob, 0) != NULL) {
|
||||
lv_coord_t knob_extra_size = lv_obj_get_draw_rect_ext_pad_size(arc, LV_ARC_PART_KNOB);
|
||||
lv_coord_t knob_extra_size = _lv_obj_get_draw_rect_ext_pad_size(arc, LV_ARC_PART_KNOB);
|
||||
|
||||
lv_coord_t knob_left = lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB);
|
||||
lv_coord_t knob_right = lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB);
|
||||
|
||||
@@ -63,7 +63,6 @@ enum {
|
||||
LV_ARC_PART_INDIC,
|
||||
LV_ARC_PART_KNOB,
|
||||
_LV_ARC_PART_VIRTUAL_LAST,
|
||||
_LV_ARC_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_arc_part_t;
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
|
||||
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part);
|
||||
|
||||
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area);
|
||||
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
@@ -56,7 +55,7 @@ static void lv_bar_anim_ready(lv_anim_t * a);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_cb_t ancestor_design_f;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**********************
|
||||
@@ -70,20 +69,21 @@ static lv_signal_cb_t ancestor_signal;
|
||||
/**
|
||||
* Create a bar objects
|
||||
* @param par pointer to an object, it will be the parent of the new bar
|
||||
* @param copy pointer to a bar object, if not NULL then the new object will be copied from it
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other bar to copy.
|
||||
* @return pointer to the created bar
|
||||
*/
|
||||
lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_bar_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("lv_bar create started");
|
||||
|
||||
/*Create the ancestor basic object*/
|
||||
lv_obj_t * bar = lv_obj_create(par, copy);
|
||||
lv_obj_t * bar = lv_obj_create(parent, copy);
|
||||
LV_ASSERT_MEM(bar);
|
||||
if(bar == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(bar);
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(bar);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(bar);
|
||||
|
||||
/*Allocate the object type specific extended data*/
|
||||
lv_bar_ext_t * ext = lv_obj_allocate_ext_attr(bar, sizeof(lv_bar_ext_t));
|
||||
@@ -109,32 +109,28 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_set_signal_cb(bar, lv_bar_signal);
|
||||
lv_obj_set_design_cb(bar, lv_bar_design);
|
||||
|
||||
|
||||
/*Init the new bar object*/
|
||||
if(copy == NULL) {
|
||||
|
||||
lv_obj_set_click(bar, false);
|
||||
lv_obj_clear_flag(bar, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_clear_flag(bar, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_set_size(bar, LV_DPI * 2, LV_DPI / 10);
|
||||
lv_bar_set_value(bar, ext->cur_value, false);
|
||||
|
||||
lv_theme_apply(bar, LV_THEME_BAR);
|
||||
} else {
|
||||
lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
|
||||
ext->min_value = ext_copy->min_value;
|
||||
ext->start_value = ext_copy->start_value;
|
||||
ext->max_value = ext_copy->max_value;
|
||||
ext->cur_value = ext_copy->cur_value;
|
||||
ext->type = ext_copy->type;
|
||||
|
||||
lv_style_list_copy(&ext->style_indic, &ext_copy->style_indic);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
_lv_obj_refresh_style(bar, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
|
||||
lv_bar_set_value(bar, ext->cur_value, LV_ANIM_OFF);
|
||||
}
|
||||
else {
|
||||
lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
|
||||
ext->min_value = ext_copy->min_value;
|
||||
ext->start_value = ext_copy->start_value;
|
||||
ext->max_value = ext_copy->max_value;
|
||||
ext->cur_value = ext_copy->cur_value;
|
||||
ext->type = ext_copy->type;
|
||||
|
||||
lv_style_list_copy(&ext->style_indic, &ext_copy->style_indic);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(bar, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
|
||||
lv_bar_set_value(bar, ext->cur_value, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("bar created");
|
||||
|
||||
return bar;
|
||||
@@ -371,10 +367,11 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
/*Return false if the object is not covers the mask area*/
|
||||
return ancestor_design_f(bar, clip_area, mode);
|
||||
return ancestor_design(bar, clip_area, mode);
|
||||
}
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
draw_bg(bar, clip_area);
|
||||
// draw_bg(bar, clip_area);
|
||||
ancestor_design(bar, clip_area, mode);
|
||||
draw_indic(bar, clip_area);
|
||||
|
||||
/*Get the value and draw it after the indicator*/
|
||||
@@ -385,44 +382,15 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
|
||||
draw_dsc.shadow_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.pattern_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.outline_opa = LV_OPA_TRANSP;
|
||||
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_BG, &draw_dsc);
|
||||
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_MAIN, &draw_dsc);
|
||||
lv_draw_rect(&bar->coords, clip_area, &draw_dsc);
|
||||
}
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
/*If the border is drawn later disable loading other properties*/
|
||||
if(lv_obj_get_style_border_post(bar, LV_OBJ_PART_MAIN)) {
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_draw_rect_dsc_init(&draw_dsc);
|
||||
draw_dsc.bg_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.pattern_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.outline_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.shadow_opa = LV_OPA_TRANSP;
|
||||
draw_dsc.value_opa = LV_OPA_TRANSP;
|
||||
lv_obj_init_draw_rect_dsc(bar, LV_OBJ_PART_MAIN, &draw_dsc);
|
||||
|
||||
lv_draw_rect(&bar->coords, clip_area, &draw_dsc);
|
||||
}
|
||||
ancestor_design(bar, clip_area, mode);
|
||||
}
|
||||
return LV_DESIGN_RES_OK;
|
||||
}
|
||||
|
||||
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area)
|
||||
{
|
||||
/*Simply draw the background*/
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_draw_rect_dsc_init(&draw_dsc);
|
||||
/*If the border is drawn later disable loading its properties*/
|
||||
if(lv_obj_get_style_border_post(bar, LV_BAR_PART_BG)) {
|
||||
draw_dsc.border_opa = LV_OPA_TRANSP;
|
||||
}
|
||||
|
||||
/*value will be drawn later*/
|
||||
draw_dsc.value_opa = LV_OPA_TRANSP;
|
||||
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_BG, &draw_dsc);
|
||||
lv_draw_rect(&bar->coords, clip_area, &draw_dsc);
|
||||
|
||||
}
|
||||
|
||||
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
|
||||
{
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
@@ -437,10 +405,10 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
|
||||
ext->start_value == ext->min_value) sym = true;
|
||||
|
||||
/*Calculate the indicator area*/
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(bar, LV_BAR_PART_BG);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(bar, LV_BAR_PART_BG);
|
||||
lv_style_int_t bg_top = lv_obj_get_style_pad_top(bar, LV_BAR_PART_BG);
|
||||
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(bar, LV_BAR_PART_BG);
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(bar, LV_BAR_PART_MAIN);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(bar, LV_BAR_PART_MAIN);
|
||||
lv_style_int_t bg_top = lv_obj_get_style_pad_top(bar, LV_BAR_PART_MAIN);
|
||||
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(bar, LV_BAR_PART_MAIN);
|
||||
|
||||
/*Respect padding and minimum width/height too*/
|
||||
lv_area_copy(&ext->indic_area, &bar->coords);
|
||||
@@ -550,7 +518,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
|
||||
/*Do not draw a zero length indicator*/
|
||||
if(!sym && indic_length_calc(&ext->indic_area) <= 1) return;
|
||||
|
||||
uint16_t bg_radius = lv_obj_get_style_radius(bar, LV_BAR_PART_BG);
|
||||
uint16_t bg_radius = lv_obj_get_style_radius(bar, LV_BAR_PART_MAIN);
|
||||
lv_coord_t short_side = LV_MATH_MIN(objw, objh);
|
||||
if(bg_radius > short_side >> 1) bg_radius = short_side >> 1;
|
||||
|
||||
@@ -645,29 +613,30 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(bar, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_bar_get_style(bar, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(bar, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(bar, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
lv_coord_t indic_size;
|
||||
indic_size = lv_obj_get_draw_rect_ext_pad_size(bar, LV_BAR_PART_INDIC);
|
||||
indic_size = _lv_obj_get_draw_rect_ext_pad_size(bar, LV_BAR_PART_INDIC);
|
||||
|
||||
/*Bg size is handled by lv_obj*/
|
||||
bar->ext_draw_pad = LV_MATH_MAX(bar->ext_draw_pad, indic_size);
|
||||
lv_coord_t * s = param;
|
||||
*s = LV_MATH_MAX(*s, indic_size);
|
||||
|
||||
}
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(bar, LV_BAR_PART_INDIC);
|
||||
_lv_obj_reset_style_list_no_refr(bar, LV_BAR_PART_INDIC);
|
||||
#if LV_USE_ANIMATION
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
lv_anim_del(&ext->cur_value_anim, NULL);
|
||||
@@ -683,20 +652,20 @@ static lv_style_list_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part)
|
||||
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
|
||||
|
||||
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
|
||||
lv_style_list_t * style_dsc_p;
|
||||
lv_style_list_t * list;
|
||||
|
||||
switch(part) {
|
||||
case LV_BAR_PART_BG:
|
||||
style_dsc_p = &bar->style_list;
|
||||
case LV_BAR_PART_MAIN:
|
||||
list = &bar->style_list;
|
||||
break;
|
||||
case LV_BAR_PART_INDIC:
|
||||
style_dsc_p = &ext->style_indic;
|
||||
list = &ext->style_indic;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
return style_dsc_p;
|
||||
return list;
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
@@ -19,7 +19,6 @@ extern "C" {
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "lv_cont.h"
|
||||
#include "lv_btn.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
@@ -80,7 +79,7 @@ typedef struct {
|
||||
|
||||
/** Bar parts */
|
||||
enum {
|
||||
LV_BAR_PART_BG, /** Bar background style. */
|
||||
LV_BAR_PART_MAIN, /** Bar background style. */
|
||||
LV_BAR_PART_INDIC, /** Bar fill area style. */
|
||||
_LV_BAR_PART_VIRTUAL_LAST
|
||||
};
|
||||
@@ -93,10 +92,11 @@ typedef uint8_t lv_bar_part_t;
|
||||
/**
|
||||
* Create a bar objects
|
||||
* @param par pointer to an object, it will be the parent of the new bar
|
||||
* @param copy pointer to a bar object, if not NULL then the new object will be copied from it
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other bar to copy.
|
||||
* @return pointer to the created bar
|
||||
*/
|
||||
lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
lv_obj_t * lv_bar_create(lv_obj_t * parent, lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_btn"
|
||||
#define LV_BTN_INK_VALUE_MAX 256
|
||||
#define LV_BTN_INK_VALUE_MAX_SHIFT 8
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -33,14 +31,12 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_design_res_t lv_btn_design(lv_obj_t * btn, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -52,56 +48,34 @@ static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**
|
||||
* Create a button object
|
||||
* @param par pointer to an object, it will be the parent of the new button
|
||||
* @param copy pointer to a button object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new button
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other button to copy.
|
||||
* @return pointer to the created button
|
||||
*/
|
||||
lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("button create started");
|
||||
|
||||
lv_obj_t * btn;
|
||||
|
||||
btn = lv_cont_create(par, copy);
|
||||
btn = lv_obj_create(parent, copy);
|
||||
LV_ASSERT_MEM(btn);
|
||||
if(btn == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(btn);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(btn);
|
||||
|
||||
/*Allocate the extended data*/
|
||||
lv_btn_ext_t * ext = lv_obj_allocate_ext_attr(btn, sizeof(lv_btn_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(btn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext->checkable = 0;
|
||||
|
||||
lv_obj_set_signal_cb(btn, lv_btn_signal);
|
||||
lv_obj_set_design_cb(btn, lv_btn_design);
|
||||
|
||||
/*If no copy do the basic initialization*/
|
||||
if(copy == NULL) {
|
||||
/*Set layout if the button is not a screen*/
|
||||
if(par) {
|
||||
if(parent) {
|
||||
lv_obj_set_size(btn, LV_DPI, LV_DPI / 3);
|
||||
lv_btn_set_layout(btn, LV_LAYOUT_CENTER);
|
||||
lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLLABLE);
|
||||
}
|
||||
|
||||
lv_obj_set_click(btn, true); /*Be sure the button is clickable*/
|
||||
|
||||
lv_theme_apply(btn, LV_THEME_BTN);
|
||||
}
|
||||
/*Copy 'copy'*/
|
||||
else {
|
||||
lv_btn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->checkable = copy_ext->checkable;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(btn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("button created");
|
||||
|
||||
@@ -112,146 +86,14 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Enable the toggled states
|
||||
* @param btn pointer to a button object
|
||||
* @param tgl true: enable toggled states, false: disable
|
||||
*/
|
||||
void lv_btn_set_checkable(lv_obj_t * btn, bool tgl)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
|
||||
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
|
||||
ext->checkable = tgl != false ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of the button
|
||||
* @param btn pointer to a button object
|
||||
* @param state the new state of the button (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
|
||||
|
||||
switch(state) {
|
||||
case LV_BTN_STATE_RELEASED:
|
||||
lv_obj_clear_state(btn, LV_STATE_PRESSED | LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
break;
|
||||
case LV_BTN_STATE_PRESSED:
|
||||
lv_obj_clear_state(btn, LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
lv_obj_add_state(btn, LV_STATE_PRESSED);
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_RELEASED:
|
||||
lv_obj_add_state(btn, LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(btn, LV_STATE_PRESSED | LV_STATE_DISABLED);
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_PRESSED:
|
||||
lv_obj_add_state(btn, LV_STATE_PRESSED | LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(btn, LV_STATE_DISABLED);
|
||||
break;
|
||||
case LV_BTN_STATE_DISABLED:
|
||||
lv_obj_clear_state(btn, LV_STATE_PRESSED | LV_STATE_CHECKED);
|
||||
lv_obj_add_state(btn, LV_STATE_DISABLED);
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_DISABLED:
|
||||
lv_obj_clear_state(btn, LV_STATE_PRESSED);
|
||||
lv_obj_add_state(btn, LV_STATE_DISABLED | LV_STATE_CHECKED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the state of the button (ON->OFF, OFF->ON)
|
||||
* @param btn pointer to a button object
|
||||
*/
|
||||
void lv_btn_toggle(lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
|
||||
|
||||
if(lv_obj_get_state(btn, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) {
|
||||
lv_obj_clear_state(btn, LV_STATE_CHECKED);
|
||||
}
|
||||
else {
|
||||
lv_obj_add_state(btn, LV_STATE_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the current state of the button
|
||||
* @param btn pointer to a button object
|
||||
* @return the state of the button (from lv_btn_state_t enum).
|
||||
* If the button is in disabled state `LV_BTN_STATE_DISABLED` will be ORed to the other button states.
|
||||
*/
|
||||
lv_btn_state_t lv_btn_get_state(const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
|
||||
|
||||
lv_state_t obj_state = lv_obj_get_state(btn, LV_BTN_PART_MAIN);
|
||||
|
||||
if(obj_state & LV_STATE_DISABLED) {
|
||||
if(obj_state & LV_STATE_CHECKED) return LV_BTN_STATE_CHECKED_DISABLED;
|
||||
else return LV_BTN_STATE_DISABLED;
|
||||
}
|
||||
|
||||
if(obj_state & LV_STATE_CHECKED) {
|
||||
if(obj_state & LV_STATE_PRESSED) return LV_BTN_STATE_CHECKED_PRESSED;
|
||||
else return LV_BTN_STATE_CHECKED_RELEASED;
|
||||
}
|
||||
else {
|
||||
if(obj_state & LV_STATE_PRESSED) return LV_BTN_STATE_PRESSED;
|
||||
else return LV_BTN_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the toggle enable attribute of the button
|
||||
* @param btn pointer to a button object
|
||||
* @return true: toggle enabled, false: disabled
|
||||
*/
|
||||
bool lv_btn_get_checkable(const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
|
||||
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
|
||||
|
||||
return ext->checkable != 0 ? true : false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the drop down lists
|
||||
* @param btn 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 an element of `lv_design_res_t`
|
||||
*/
|
||||
static lv_design_res_t lv_btn_design(lv_obj_t * btn, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_design(btn, clip_area, mode);
|
||||
}
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
ancestor_design(btn, clip_area, mode);
|
||||
}
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_design(btn, clip_area, mode);
|
||||
}
|
||||
|
||||
return LV_DESIGN_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the button
|
||||
* @param btn pointer to a button object
|
||||
@@ -266,51 +108,9 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(btn, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
bool tgl = lv_btn_get_checkable(btn);
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED) {
|
||||
/*If not dragged and it was not long press action then
|
||||
*change state and run the action*/
|
||||
if(lv_indev_is_dragging(param) == false && tgl) {
|
||||
uint32_t toggled = 0;
|
||||
if(lv_obj_get_state(btn, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_RELEASED);
|
||||
toggled = 0;
|
||||
}
|
||||
else {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_CHECKED_RELEASED);
|
||||
toggled = 1;
|
||||
}
|
||||
|
||||
res = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &toggled);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
#if LV_USE_GROUP
|
||||
char c = *((char *)param);
|
||||
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
|
||||
if(lv_btn_get_checkable(btn)) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_CHECKED_RELEASED);
|
||||
|
||||
uint32_t state = 1;
|
||||
res = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &state);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
|
||||
}
|
||||
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
|
||||
if(lv_btn_get_checkable(btn)) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_RELEASED);
|
||||
|
||||
uint32_t state = 0;
|
||||
res = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &state);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@@ -17,12 +17,6 @@ extern "C" {
|
||||
|
||||
#if LV_USE_BTN != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_CONT == 0
|
||||
#error "lv_btn: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT 1) "
|
||||
#endif
|
||||
|
||||
#include "lv_cont.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
|
||||
/*********************
|
||||
@@ -33,33 +27,9 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Possible states of a button.
|
||||
* It can be used not only by buttons but other button-like objects too*/
|
||||
enum {
|
||||
LV_BTN_STATE_RELEASED,
|
||||
LV_BTN_STATE_PRESSED,
|
||||
LV_BTN_STATE_DISABLED,
|
||||
LV_BTN_STATE_CHECKED_RELEASED,
|
||||
LV_BTN_STATE_CHECKED_PRESSED,
|
||||
LV_BTN_STATE_CHECKED_DISABLED,
|
||||
_LV_BTN_STATE_LAST, /* Number of states*/
|
||||
};
|
||||
typedef uint8_t lv_btn_state_t;
|
||||
|
||||
/** Extended data of button*/
|
||||
typedef struct {
|
||||
/** Ext. of ancestor*/
|
||||
lv_cont_ext_t cont;
|
||||
|
||||
/** 1: Toggle enabled*/
|
||||
uint8_t checkable : 1;
|
||||
} lv_btn_ext_t;
|
||||
|
||||
/**Styles*/
|
||||
enum {
|
||||
LV_BTN_PART_MAIN = LV_OBJ_PART_MAIN,
|
||||
_LV_BTN_PART_VIRTUAL_LAST,
|
||||
_LV_BTN_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_btn_part_t;
|
||||
|
||||
@@ -69,152 +39,21 @@ typedef uint8_t lv_btn_part_t;
|
||||
|
||||
/**
|
||||
* Create a button object
|
||||
* @param par pointer to an object, it will be the parent of the new button
|
||||
* @param copy pointer to a button object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new button
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other button to copy.
|
||||
* @return pointer to the created button
|
||||
*/
|
||||
lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Enable the toggled states. On release the button will change from/to toggled state.
|
||||
* @param btn pointer to a button object
|
||||
* @param tgl true: enable toggled states, false: disable
|
||||
*/
|
||||
void lv_btn_set_checkable(lv_obj_t * btn, bool tgl);
|
||||
|
||||
/**
|
||||
* Set the state of the button
|
||||
* @param btn pointer to a button object
|
||||
* @param state the new state of the button (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state);
|
||||
|
||||
/**
|
||||
* Toggle the state of the button (ON->OFF, OFF->ON)
|
||||
* @param btn pointer to a button object
|
||||
*/
|
||||
void lv_btn_toggle(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Set the layout on a button
|
||||
* @param btn pointer to a button object
|
||||
* @param layout a layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
static inline void lv_btn_set_layout(lv_obj_t * btn, lv_layout_t layout)
|
||||
{
|
||||
lv_cont_set_layout(btn, layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 directions separately.
|
||||
* It tells how to change the button size automatically.
|
||||
* @param btn pointer to a button object
|
||||
* @param left left fit policy from `lv_fit_t`
|
||||
* @param right right fit policy from `lv_fit_t`
|
||||
* @param top top fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_btn_set_fit4(lv_obj_t * btn, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)
|
||||
{
|
||||
lv_cont_set_fit4(btn, left, right, top, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy horizontally and vertically separately.
|
||||
* It tells how to change the button size automatically.
|
||||
* @param btn pointer to a button object
|
||||
* @param hor horizontal fit policy from `lv_fit_t`
|
||||
* @param ver vertical fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_btn_set_fit2(lv_obj_t * btn, lv_fit_t hor, lv_fit_t ver)
|
||||
{
|
||||
lv_cont_set_fit2(btn, hor, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 direction at once.
|
||||
* It tells how to change the button size automatically.
|
||||
* @param btn pointer to a button object
|
||||
* @param fit fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_btn_set_fit(lv_obj_t * btn, lv_fit_t fit)
|
||||
{
|
||||
lv_cont_set_fit(btn, fit);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the current state of the button
|
||||
* @param btn pointer to a button object
|
||||
* @return the state of the button (from lv_btn_state_t enum)
|
||||
* If the button is in disabled state `LV_BTN_STATE_DISABLED` will be ORed to the other button states.
|
||||
*/
|
||||
lv_btn_state_t lv_btn_get_state(const lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the toggle enable attribute of the button
|
||||
* @param btn pointer to a button object
|
||||
* @return true: checkable enabled, false: disabled
|
||||
*/
|
||||
bool lv_btn_get_checkable(const lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the layout of a button
|
||||
* @param btn pointer to button object
|
||||
* @return the layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
static inline lv_layout_t lv_btn_get_layout(const lv_obj_t * btn)
|
||||
{
|
||||
return lv_cont_get_layout(btn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left fit mode
|
||||
* @param btn pointer to a button object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_btn_get_fit_left(const lv_obj_t * btn)
|
||||
{
|
||||
return lv_cont_get_fit_left(btn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right fit mode
|
||||
* @param btn pointer to a button object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_btn_get_fit_right(const lv_obj_t * btn)
|
||||
{
|
||||
return lv_cont_get_fit_right(btn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top fit mode
|
||||
* @param btn pointer to a button object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_btn_get_fit_top(const lv_obj_t * btn)
|
||||
{
|
||||
return lv_cont_get_fit_top(btn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bottom fit mode
|
||||
* @param btn pointer to a button object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_btn_get_fit_bottom(const lv_obj_t * btn)
|
||||
{
|
||||
return lv_cont_get_fit_bottom(btn);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -39,11 +39,12 @@ static bool button_is_repeat_disabled(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_is_inactive(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_is_click_trig(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_is_tgl_enabled(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_get_tgl_state(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_get_checked(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static bool button_is_type2(lv_btnmatrix_ctrl_t ctrl_bits);
|
||||
static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p);
|
||||
static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map);
|
||||
static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx);
|
||||
static void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx);
|
||||
static void make_one_button_checked(lv_obj_t * btnm, uint16_t btn_idx);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -97,7 +98,9 @@ lv_obj_t * lv_btnmatrix_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->recolor = 0;
|
||||
ext->one_check = 0;
|
||||
lv_style_list_init(&ext->style_btn);
|
||||
lv_style_list_init(&ext->style_btn2);
|
||||
ext->style_btn.ignore_trans = 1;
|
||||
ext->style_btn2.ignore_trans = 1;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(btnm);
|
||||
|
||||
@@ -139,119 +142,86 @@ void lv_btnmatrix_set_map(lv_obj_t * btnm, const char * map[])
|
||||
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
|
||||
LV_ASSERT_NULL(map);
|
||||
|
||||
/*
|
||||
* lv_btnmatrix_set_map is called on receipt of signals such as
|
||||
* LV_SIGNAL_CORD_CHG regardless of whether the map has changed (e.g.
|
||||
* calling lv_obj_align on the map will trigger this).
|
||||
*
|
||||
* We check if the map has changed here to avoid overwriting changes made
|
||||
* to hidden/longpress/disabled states after the map was originally set.
|
||||
*
|
||||
* TODO: separate all map set/allocation from layout code below and skip
|
||||
* set/allocation when map hasn't changed.
|
||||
*/
|
||||
lv_btnmatrix_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
|
||||
/*Analyze the map and create the required number of buttons*/
|
||||
allocate_btn_areas_and_controls(btnm, map);
|
||||
ext->map_p = map;
|
||||
|
||||
/*Set size and positions of the buttons*/
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t inner = lv_obj_get_style_pad_inner(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm);
|
||||
|
||||
lv_coord_t max_w = lv_obj_get_width(btnm) - left - right;
|
||||
lv_coord_t max_h = lv_obj_get_height(btnm) - top - bottom;
|
||||
lv_coord_t act_y = top;
|
||||
/*Set size and positions of the buttons*/
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_coord_t row_gap = LV_MATH_MAX(lv_obj_get_style_margin_top(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_bottom(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
lv_coord_t col_gap = LV_MATH_MAX(lv_obj_get_style_margin_left(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_right(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
|
||||
lv_coord_t max_w = lv_obj_get_width_fit(btnm);
|
||||
lv_coord_t max_h = lv_obj_get_height_fit(btnm);
|
||||
|
||||
/*Count the lines to calculate button height*/
|
||||
uint8_t line_cnt = 1;
|
||||
uint8_t li;
|
||||
for(li = 0; strlen(map[li]) != 0; li++) {
|
||||
if(strcmp(map[li], "\n") == 0) line_cnt++;
|
||||
uint8_t row_cnt = 1;
|
||||
uint32_t i;
|
||||
for(i = 0; strlen(map[i]) != 0; i++) {
|
||||
if(strcmp(map[i], "\n") == 0) row_cnt++;
|
||||
}
|
||||
|
||||
lv_coord_t btn_h = max_h - ((line_cnt - 1) * inner);
|
||||
btn_h = (btn_h + line_cnt / 2) / line_cnt;
|
||||
btn_h--; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/
|
||||
/*Calculate the position of each row*/
|
||||
lv_coord_t max_h_no_gap = max_h - (row_gap * (row_cnt - 1));
|
||||
|
||||
/* Count the units and the buttons in a line
|
||||
* (A button can be 1,2,3... unit wide)*/
|
||||
uint16_t unit_act_cnt; /*Number of units currently put in a row*/
|
||||
uint16_t i_tot = 0; /*Act. index in the str map*/
|
||||
uint16_t btn_i = 0; /*Act. index of button areas*/
|
||||
const char ** map_p_tmp = map;
|
||||
uint32_t txt_tot_i = 0; /*Act. index in the str map*/
|
||||
uint32_t btn_tot_i = 0; /*Act. index of button areas*/
|
||||
const char ** map_row = map;
|
||||
|
||||
/*Count the units and the buttons in a line*/
|
||||
while(1) {
|
||||
uint32_t row;
|
||||
for(row = 0; row < row_cnt; row++) {
|
||||
uint16_t unit_cnt = 0; /*Number of units in a row*/
|
||||
uint16_t btn_cnt = 0; /*Number of buttons in a row*/
|
||||
/*Count the buttons in a line*/
|
||||
while(strcmp(map_p_tmp[btn_cnt], "\n") != 0 && strlen(map_p_tmp[btn_cnt]) != 0) { /*Check a line*/
|
||||
unit_cnt += get_button_width(ext->ctrl_bits[btn_i + btn_cnt]);
|
||||
/*Count the buttons and units in this row*/
|
||||
while(strcmp(map_row[btn_cnt], "\n") != 0 && strlen(map_row[btn_cnt]) != '\0') {
|
||||
unit_cnt += get_button_width(ext->ctrl_bits[btn_tot_i + btn_cnt]);
|
||||
btn_cnt++;
|
||||
}
|
||||
|
||||
/*Make sure the last row is at the bottom of 'btnm'*/
|
||||
if(map_p_tmp[btn_cnt][0] == '\0') { /*Last row?*/
|
||||
btn_h = lv_obj_get_height(btnm) - act_y - bottom - 1;
|
||||
}
|
||||
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm);
|
||||
|
||||
/*Only deal with the non empty lines*/
|
||||
if(btn_cnt != 0) {
|
||||
/*Calculate the width of all units*/
|
||||
lv_coord_t all_unit_w = max_w - ((unit_cnt - 1) * inner);
|
||||
|
||||
/*Set the button size and positions and set the texts*/
|
||||
uint16_t i;
|
||||
lv_coord_t act_x;
|
||||
|
||||
unit_act_cnt = 0;
|
||||
for(i = 0; i < btn_cnt; i++) {
|
||||
uint8_t btn_unit_w = get_button_width(ext->ctrl_bits[btn_i]);
|
||||
/* one_unit_w = all_unit_w / unit_cnt
|
||||
* act_unit_w = one_unit_w * button_width
|
||||
* do this two operations but the multiply first to divide a greater number */
|
||||
lv_coord_t act_unit_w = (all_unit_w * btn_unit_w) / unit_cnt + inner * (btn_unit_w - 1);
|
||||
act_unit_w--; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/
|
||||
|
||||
/*Always recalculate act_x because of rounding errors */
|
||||
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + unit_act_cnt * inner;
|
||||
act_x = lv_obj_get_width(btnm) - right - act_x - act_unit_w - 1;
|
||||
}
|
||||
else {
|
||||
act_x = (unit_act_cnt * all_unit_w) / unit_cnt + unit_act_cnt * inner +
|
||||
left;
|
||||
}
|
||||
/* Set the button's area.
|
||||
* If inner padding is zero then use the prev. button x2 as x1 to avoid rounding
|
||||
* errors*/
|
||||
if(btn_i != 0 && inner == 0 && ((act_x != left && base_dir != LV_BIDI_DIR_RTL) ||
|
||||
(act_x + act_unit_w == max_w - right && base_dir == LV_BIDI_DIR_RTL))) {
|
||||
lv_area_set(&ext->button_areas[btn_i], ext->button_areas[btn_i - 1].x2, act_y, act_x + act_unit_w,
|
||||
act_y + btn_h);
|
||||
}
|
||||
else {
|
||||
lv_area_set(&ext->button_areas[btn_i], act_x, act_y, act_x + act_unit_w, act_y + btn_h);
|
||||
}
|
||||
|
||||
unit_act_cnt += btn_unit_w;
|
||||
|
||||
i_tot++;
|
||||
btn_i++;
|
||||
}
|
||||
if(btn_cnt == 0) {
|
||||
map_row = &map_row[btn_cnt + 1]; /*Set the map to the next row*/
|
||||
continue;
|
||||
}
|
||||
act_y += btn_h + inner + 1;
|
||||
|
||||
if(strlen(map_p_tmp[btn_cnt]) == 0) break; /*Break on end of map*/
|
||||
map_p_tmp = &map_p_tmp[btn_cnt + 1]; /*Set the map to the next line*/
|
||||
i_tot++; /*Skip the '\n'*/
|
||||
lv_coord_t row_y1 = top + (max_h_no_gap * row) / row_cnt + row * row_gap;
|
||||
lv_coord_t row_y2 = top + (max_h_no_gap * (row + 1)) / row_cnt + row * row_gap - 1;
|
||||
|
||||
/*Set the button size and positions*/
|
||||
lv_coord_t max_w_no_gap = max_w - (col_gap * (btn_cnt - 1));
|
||||
if(max_w_no_gap < 0) max_w_no_gap = 0;
|
||||
|
||||
uint32_t row_unit_cnt = 0; /*The current unit position in the row*/
|
||||
uint32_t btn;
|
||||
for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) {
|
||||
uint32_t btn_u = get_button_width(ext->ctrl_bits[btn_tot_i]);
|
||||
|
||||
lv_coord_t btn_x1 = left + (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * col_gap;
|
||||
lv_coord_t btn_x2 = left + (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * col_gap - 1;
|
||||
|
||||
/*If RTL start from the right*/
|
||||
if(base_dir == LV_BIDI_DIR_RTL) {
|
||||
lv_coord_t tmp = btn_x1;
|
||||
btn_x1 = btn_x2;
|
||||
btn_x2 = tmp;
|
||||
btn_x1 = max_w - btn_x1;
|
||||
btn_x2 = max_w - btn_x2;
|
||||
}
|
||||
|
||||
lv_area_set(&ext->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2);
|
||||
|
||||
row_unit_cnt += btn_u;
|
||||
}
|
||||
|
||||
map_row = &map_row[btn_cnt + 1]; /*Set the map to the next line*/
|
||||
}
|
||||
|
||||
lv_obj_invalidate(btnm);
|
||||
@@ -327,10 +297,8 @@ void lv_btnmatrix_set_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ct
|
||||
|
||||
if(btn_id >= ext->btn_cnt) return;
|
||||
|
||||
/*Uncheck all buttons if required*/
|
||||
if(ext->one_check && (ctrl & LV_BTNMATRIX_CTRL_CHECK_STATE)) {
|
||||
lv_btnmatrix_clear_btn_ctrl_all(btnm, LV_BTNMATRIX_CTRL_CHECK_STATE);
|
||||
ext->btn_id_act = btn_id;
|
||||
if(ext->one_check && (ctrl & LV_BTNMATRIX_CTRL_CHECKED)) {
|
||||
lv_btnmatrix_clear_btn_ctrl_all(btnm, LV_BTNMATRIX_CTRL_CHECKED);
|
||||
}
|
||||
|
||||
ext->ctrl_bits[btn_id] |= ctrl;
|
||||
@@ -410,13 +378,13 @@ void lv_btnmatrix_set_btn_width(lv_obj_t * btnm, uint16_t btn_id, uint8_t width)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the button matrix like a selector widget (only one button may be toggled at a time).
|
||||
* Make the button matrix like a selector widget (only one button may be checked at a time).
|
||||
* `Checkable` must be enabled on the buttons you want to be selected with `lv_btnmatrix_set_ctrl` or
|
||||
* `lv_btnmatrix_set_btn_ctrl_all`.
|
||||
* @param btnm Button matrix object
|
||||
* @param one_chk Whether "one check" mode is enabled
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param one_chk whether "one check" mode is enabled
|
||||
*/
|
||||
void lv_btnmatrix_set_one_check(lv_obj_t * btnm, bool one_chk)
|
||||
void lv_btnmatrix_set_one_checked(lv_obj_t * btnm, bool one_chk)
|
||||
{
|
||||
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
|
||||
|
||||
@@ -424,7 +392,7 @@ void lv_btnmatrix_set_one_check(lv_obj_t * btnm, bool one_chk)
|
||||
ext->one_check = one_chk;
|
||||
|
||||
/*If more than one button is toggled only the first one should be*/
|
||||
make_one_button_toggled(btnm, 0);
|
||||
make_one_button_checked(btnm, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,7 +400,7 @@ void lv_btnmatrix_set_one_check(lv_obj_t * btnm, bool one_chk)
|
||||
* @param btnm pointer to a btnmatrix object
|
||||
* @param align LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER
|
||||
*/
|
||||
void lv_btnmatrix_set_align(lv_obj_t * btnm, lv_label_align_t align)
|
||||
void lv_btnmatrix_set_text_align(lv_obj_t * btnm, lv_label_align_t align)
|
||||
{
|
||||
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
|
||||
|
||||
@@ -576,7 +544,7 @@ bool lv_btnmatrix_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ct
|
||||
* @param btnm Button matrix object
|
||||
* @return whether "one check" mode is enabled
|
||||
*/
|
||||
bool lv_btnmatrix_get_one_check(const lv_obj_t * btnm)
|
||||
bool lv_btnmatrix_get_one_checked(const lv_obj_t * btnm)
|
||||
{
|
||||
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
|
||||
|
||||
@@ -677,8 +645,8 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
|
||||
bool chk_inited = false;
|
||||
bool disabled_inited = false;
|
||||
|
||||
lv_style_int_t padding_top = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t padding_bottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t padding_top = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_style_int_t padding_bottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
const size_t txt_ap_size = 256 ;
|
||||
@@ -706,19 +674,20 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
|
||||
lv_draw_rect_dsc_t * draw_rect_dsc_act;
|
||||
lv_draw_label_dsc_t * draw_label_dsc_act;
|
||||
lv_state_t btn_state = LV_STATE_DEFAULT;
|
||||
if(button_get_tgl_state(ext->ctrl_bits[btn_i])) btn_state |= LV_STATE_CHECKED;
|
||||
if(button_get_checked(ext->ctrl_bits[btn_i])) btn_state |= LV_STATE_CHECKED;
|
||||
if(button_is_inactive(ext->ctrl_bits[btn_i])) btn_state |= LV_STATE_DISABLED;
|
||||
if(btn_i == ext->btn_id_pr) btn_state |= LV_STATE_PRESSED;
|
||||
if(btn_i == ext->btn_id_focused) {
|
||||
btn_state |= LV_STATE_FOCUSED;
|
||||
if(state_ori & LV_STATE_EDITED) btn_state |= LV_STATE_EDITED;
|
||||
}
|
||||
bool type2 = button_is_type2(ext->ctrl_bits[btn_i]);
|
||||
|
||||
if(btn_state == LV_STATE_DEFAULT) {
|
||||
if(btn_state == LV_STATE_DEFAULT && type2 == false) {
|
||||
draw_rect_dsc_act = &draw_rect_rel_dsc;
|
||||
draw_label_dsc_act = &draw_label_rel_dsc;
|
||||
}
|
||||
else if(btn_state == LV_STATE_CHECKED) {
|
||||
else if(btn_state == LV_STATE_CHECKED && type2 == false) {
|
||||
if(!chk_inited) {
|
||||
btnm->state = LV_STATE_CHECKED;
|
||||
_lv_obj_disable_style_caching(btnm, true);
|
||||
@@ -734,7 +703,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
|
||||
draw_rect_dsc_act = &draw_rect_chk_dsc;
|
||||
draw_label_dsc_act = &draw_label_chk_dsc;
|
||||
}
|
||||
else if(btn_state == LV_STATE_DISABLED) {
|
||||
else if(btn_state == LV_STATE_DISABLED && type2 == false) {
|
||||
if(!disabled_inited) {
|
||||
btnm->state = LV_STATE_DISABLED;
|
||||
_lv_obj_disable_style_caching(btnm, true);
|
||||
@@ -756,8 +725,8 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
|
||||
_lv_obj_disable_style_caching(btnm, true);
|
||||
lv_draw_rect_dsc_init(&draw_rect_tmp_dsc);
|
||||
lv_draw_label_dsc_init(&draw_label_tmp_dsc);
|
||||
lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_tmp_dsc);
|
||||
lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_tmp_dsc);
|
||||
lv_obj_init_draw_rect_dsc(btnm, type2 ? LV_BTNMATRIX_PART_BTN_2 : LV_BTNMATRIX_PART_BTN, &draw_rect_tmp_dsc);
|
||||
lv_obj_init_draw_label_dsc(btnm, type2 ? LV_BTNMATRIX_PART_BTN_2 : LV_BTNMATRIX_PART_BTN, &draw_label_tmp_dsc);
|
||||
draw_label_tmp_dsc.flag = txt_flag;
|
||||
draw_rect_dsc_act = &draw_rect_tmp_dsc;
|
||||
draw_label_dsc_act = &draw_label_tmp_dsc;
|
||||
@@ -851,12 +820,12 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(btnm, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_btnmatrix_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
lv_point_t p;
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(btnm, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_obj_reset_style_list_no_refr(btnm, LV_BTNMATRIX_PART_BTN);
|
||||
lv_mem_free(ext->button_areas);
|
||||
lv_mem_free(ext->ctrl_bits);
|
||||
}
|
||||
@@ -864,7 +833,9 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
lv_btnmatrix_set_map(btnm, ext->map_p);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
if(lv_obj_get_width(btnm) != lv_area_get_width(param) || lv_obj_get_height(btnm) != lv_area_get_height(param)) {
|
||||
if(param &&
|
||||
(lv_obj_get_width(btnm) != lv_area_get_width(param) || lv_obj_get_height(btnm) != lv_area_get_height(param)))
|
||||
{
|
||||
lv_btnmatrix_set_map(btnm, ext->map_p);
|
||||
}
|
||||
}
|
||||
@@ -941,20 +912,19 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
/*Toggle the button if enabled*/
|
||||
if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr]) &&
|
||||
!button_is_inactive(ext->ctrl_bits[ext->btn_id_pr])) {
|
||||
if(button_get_tgl_state(ext->ctrl_bits[ext->btn_id_pr]) && !ext->one_check) {
|
||||
ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNMATRIX_CTRL_CHECK_STATE);
|
||||
if(button_get_checked(ext->ctrl_bits[ext->btn_id_pr]) && !ext->one_check) {
|
||||
ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNMATRIX_CTRL_CHECKED);
|
||||
}
|
||||
else {
|
||||
ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNMATRIX_CTRL_CHECK_STATE;
|
||||
ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNMATRIX_CTRL_CHECKED;
|
||||
}
|
||||
if(ext->one_check) make_one_button_toggled(btnm, ext->btn_id_pr);
|
||||
if(ext->one_check) make_one_button_checked(btnm, ext->btn_id_pr);
|
||||
}
|
||||
|
||||
/*Invalidate to old pressed area*/;
|
||||
invalidate_button_area(btnm, ext->btn_id_pr);
|
||||
invalidate_button_area(btnm, ext->btn_id_focused);
|
||||
|
||||
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
ext->btn_id_focused = ext->btn_id_pr;
|
||||
@@ -1000,7 +970,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
/*In navigation mode don't select any button but in edit mode select the fist*/
|
||||
if(lv_group_get_editing(lv_obj_get_group(btnm))) {
|
||||
ext->btn_id_focused = 0;
|
||||
ext->btn_id_act = ext->btn_id_focused;
|
||||
ext->btn_id_act = 0;
|
||||
}
|
||||
else {
|
||||
ext->btn_id_focused = LV_BTNMATRIX_BTN_NONE;
|
||||
@@ -1008,7 +978,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
}
|
||||
else if(indev_type == LV_INDEV_TYPE_KEYPAD) {
|
||||
ext->btn_id_focused = 0;
|
||||
ext->btn_id_act = ext->btn_id_focused;
|
||||
ext->btn_id_act = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1039,7 +1009,8 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(c == LV_KEY_DOWN) {
|
||||
lv_style_int_t pad_inner = lv_obj_get_style_pad_inner(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_coord_t col_gap = LV_MATH_MAX(lv_obj_get_style_margin_left(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_right(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
|
||||
/*Find the area below the the current*/
|
||||
if(ext->btn_id_focused == LV_BTNMATRIX_BTN_NONE) {
|
||||
ext->btn_id_focused = 0;
|
||||
@@ -1052,7 +1023,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
for(area_below = ext->btn_id_focused; area_below < ext->btn_cnt; area_below++) {
|
||||
if(ext->button_areas[area_below].y1 > ext->button_areas[ext->btn_id_focused].y1 &&
|
||||
pr_center >= ext->button_areas[area_below].x1 &&
|
||||
pr_center <= ext->button_areas[area_below].x2 + pad_inner &&
|
||||
pr_center <= ext->button_areas[area_below].x2 + col_gap &&
|
||||
button_is_inactive(ext->ctrl_bits[area_below]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[area_below]) == false) {
|
||||
break;
|
||||
@@ -1065,7 +1036,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
lv_obj_invalidate(btnm);
|
||||
}
|
||||
else if(c == LV_KEY_UP) {
|
||||
lv_style_int_t pad_inner = lv_obj_get_style_pad_inner(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_coord_t col_gap = LV_MATH_MAX(lv_obj_get_style_margin_left(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_right(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
/*Find the area below the the current*/
|
||||
if(ext->btn_id_focused == LV_BTNMATRIX_BTN_NONE) {
|
||||
ext->btn_id_focused = 0;
|
||||
@@ -1077,7 +1048,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa
|
||||
|
||||
for(area_above = ext->btn_id_focused; area_above >= 0; area_above--) {
|
||||
if(ext->button_areas[area_above].y1 < ext->button_areas[ext->btn_id_focused].y1 &&
|
||||
pr_center >= ext->button_areas[area_above].x1 - pad_inner &&
|
||||
pr_center >= ext->button_areas[area_above].x1 - col_gap &&
|
||||
pr_center <= ext->button_areas[area_above].x2 &&
|
||||
button_is_inactive(ext->ctrl_bits[area_above]) == false &&
|
||||
button_is_hidden(ext->ctrl_bits[area_above]) == false) {
|
||||
@@ -1115,12 +1086,15 @@ static lv_style_list_t * lv_btnmatrix_get_style(lv_obj_t * btnm, uint8_t part)
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_BTNMATRIX_PART_BG:
|
||||
case LV_BTNMATRIX_PART_MAIN:
|
||||
style_dsc_p = &btnm->style_list;
|
||||
break;
|
||||
case LV_BTNMATRIX_PART_BTN:
|
||||
style_dsc_p = &ext->style_btn;
|
||||
break;
|
||||
case LV_BTNMATRIX_PART_BTN_2:
|
||||
style_dsc_p = &ext->style_btn2;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
}
|
||||
@@ -1207,11 +1181,17 @@ static bool button_is_tgl_enabled(lv_btnmatrix_ctrl_t ctrl_bits)
|
||||
return (ctrl_bits & LV_BTNMATRIX_CTRL_CHECKABLE) ? true : false;
|
||||
}
|
||||
|
||||
static bool button_get_tgl_state(lv_btnmatrix_ctrl_t ctrl_bits)
|
||||
static bool button_get_checked(lv_btnmatrix_ctrl_t ctrl_bits)
|
||||
{
|
||||
return (ctrl_bits & LV_BTNMATRIX_CTRL_CHECK_STATE) ? true : false;
|
||||
return (ctrl_bits & LV_BTNMATRIX_CTRL_CHECKED) ? true : false;
|
||||
}
|
||||
|
||||
static bool button_is_type2(lv_btnmatrix_ctrl_t ctrl_bits)
|
||||
{
|
||||
return (ctrl_bits & LV_BTNMATRIX_CTRL_TYPE_2) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gives the button id of a button under a given point
|
||||
* @param btnm pointer to a button matrix object
|
||||
@@ -1228,16 +1208,20 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p)
|
||||
|
||||
lv_coord_t w = lv_obj_get_width(btnm);
|
||||
lv_coord_t h = lv_obj_get_height(btnm);
|
||||
lv_style_int_t pleft = lv_obj_get_style_pad_left(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t pright = lv_obj_get_style_pad_right(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t ptop = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t pbottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t pinner = lv_obj_get_style_pad_inner(btnm, LV_BTNMATRIX_PART_BG);
|
||||
lv_style_int_t pleft = lv_obj_get_style_pad_left(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_style_int_t pright = lv_obj_get_style_pad_right(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_style_int_t ptop = lv_obj_get_style_pad_top(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_style_int_t pbottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNMATRIX_PART_MAIN);
|
||||
lv_coord_t row_gap = LV_MATH_MAX(lv_obj_get_style_margin_top(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_bottom(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
lv_coord_t col_gap = LV_MATH_MAX(lv_obj_get_style_margin_left(btnm, LV_BTNMATRIX_PART_BTN), lv_obj_get_style_margin_right(btnm, LV_BTNMATRIX_PART_BTN));
|
||||
|
||||
/*Get the half inner padding. Button look larger with this value. (+1 for rounding error)*/
|
||||
pinner = (pinner / 2) + 1 + (pinner & 1);
|
||||
|
||||
pinner = LV_MATH_MIN(pinner, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
/*Get the half gap. Button look larger with this value. (+1 for rounding error)*/
|
||||
row_gap = (row_gap / 2) + 1 + (row_gap & 1);
|
||||
col_gap = (col_gap / 2) + 1 + (col_gap & 1);
|
||||
|
||||
row_gap = LV_MATH_MIN(row_gap, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
col_gap = LV_MATH_MIN(col_gap, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
pright = LV_MATH_MIN(pright, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
ptop = LV_MATH_MIN(ptop, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
pbottom = LV_MATH_MIN(pbottom, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
@@ -1245,18 +1229,18 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p)
|
||||
for(i = 0; i < ext->btn_cnt; i++) {
|
||||
lv_area_copy(&btn_area, &ext->button_areas[i]);
|
||||
if(btn_area.x1 <= pleft) btn_area.x1 += btnm_cords.x1 - LV_MATH_MIN(pleft, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
else btn_area.x1 += btnm_cords.x1 - pinner;
|
||||
else btn_area.x1 += btnm_cords.x1 - col_gap;
|
||||
|
||||
if(btn_area.y1 <= ptop) btn_area.y1 += btnm_cords.y1 - LV_MATH_MIN(ptop, BTN_EXTRA_CLICK_AREA_MAX);
|
||||
else btn_area.y1 += btnm_cords.y1 - pinner;
|
||||
else btn_area.y1 += btnm_cords.y1 - row_gap;
|
||||
|
||||
if(btn_area.x2 >= w - pright - 2) btn_area.x2 += btnm_cords.x1 + LV_MATH_MIN(pright,
|
||||
BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/
|
||||
else btn_area.x2 += btnm_cords.x1 + pinner;
|
||||
else btn_area.x2 += btnm_cords.x1 + col_gap;
|
||||
|
||||
if(btn_area.y2 >= h - pbottom - 2) btn_area.y2 += btnm_cords.y1 + LV_MATH_MIN(pbottom,
|
||||
BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/
|
||||
else btn_area.y2 += btnm_cords.y1 + pinner;
|
||||
else btn_area.y2 += btnm_cords.y1 + row_gap;
|
||||
|
||||
if(_lv_area_is_point_on(&btn_area, p, 0) != false) {
|
||||
break;
|
||||
@@ -1294,14 +1278,14 @@ static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx)
|
||||
* @param btnm Button matrix object
|
||||
* @param btn_idx Button that should remain toggled
|
||||
*/
|
||||
static void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx)
|
||||
static void make_one_button_checked(lv_obj_t * btnm, uint16_t btn_idx)
|
||||
{
|
||||
/*Save whether the button was toggled*/
|
||||
bool was_toggled = lv_btnmatrix_get_btn_ctrl(btnm, btn_idx, LV_BTNMATRIX_CTRL_CHECK_STATE);
|
||||
bool was_toggled = lv_btnmatrix_get_btn_ctrl(btnm, btn_idx, LV_BTNMATRIX_CTRL_CHECKED);
|
||||
|
||||
lv_btnmatrix_clear_btn_ctrl_all(btnm, LV_BTNMATRIX_CTRL_CHECK_STATE);
|
||||
lv_btnmatrix_clear_btn_ctrl_all(btnm, LV_BTNMATRIX_CTRL_CHECKED);
|
||||
|
||||
if(was_toggled) lv_btnmatrix_set_btn_ctrl(btnm, btn_idx, LV_BTNMATRIX_CTRL_CHECK_STATE);
|
||||
if(was_toggled) lv_btnmatrix_set_btn_ctrl(btnm, btn_idx, LV_BTNMATRIX_CTRL_CHECKED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,8 +40,9 @@ enum {
|
||||
LV_BTNMATRIX_CTRL_NO_REPEAT = 0x0010, /**< Do not repeat press this button. */
|
||||
LV_BTNMATRIX_CTRL_DISABLED = 0x0020, /**< Disable this button. */
|
||||
LV_BTNMATRIX_CTRL_CHECKABLE = 0x0040, /**< Button *can* be toggled. */
|
||||
LV_BTNMATRIX_CTRL_CHECK_STATE = 0x0080, /**< Button is currently toggled (e.g. checked). */
|
||||
LV_BTNMATRIX_CTRL_CLICK_TRIG = 0x0100, /**< 1: Send LV_EVENT_SELECTED on CLICK, 0: Send LV_EVENT_SELECTED on PRESS*/
|
||||
LV_BTNMATRIX_CTRL_CHECKED = 0x0080, /**< Button is currently toggled (e.g. checked). */
|
||||
LV_BTNMATRIX_CTRL_CLICK_TRIG = 0x0100, /**< 1: Send LV_EVENT_VALUE_CHANGE on CLICK, 0: Send LV_EVENT_VALUE_CHANGE on PRESS*/
|
||||
LV_BTNMATRIX_CTRL_TYPE_2 = 0x0200, /**< Render the button with `LV_BTNMATRIX_PART_BTN2` style*/
|
||||
};
|
||||
typedef uint16_t lv_btnmatrix_ctrl_t;
|
||||
|
||||
@@ -52,7 +53,8 @@ typedef struct {
|
||||
const char ** map_p; /*Pointer to the current map*/
|
||||
lv_area_t * button_areas; /*Array of areas of buttons*/
|
||||
lv_btnmatrix_ctrl_t * ctrl_bits; /*Array of control bytes*/
|
||||
lv_style_list_t style_btn; /*Styles of buttons in each state*/
|
||||
lv_style_list_t style_btn; /*Styles of buttons in each state*/
|
||||
lv_style_list_t style_btn2; /*Styles of buttons in each state with LV_BTNMATRIX_CTRL_TYPE_2 control*/
|
||||
uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/
|
||||
uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNMATRIX_BTN_NONE*/
|
||||
uint16_t btn_id_focused; /*Index of the currently focused button or LV_BTNMATRIX_BTN_NONE*/
|
||||
@@ -63,8 +65,9 @@ typedef struct {
|
||||
} lv_btnmatrix_ext_t;
|
||||
|
||||
enum {
|
||||
LV_BTNMATRIX_PART_BG,
|
||||
LV_BTNMATRIX_PART_MAIN,
|
||||
LV_BTNMATRIX_PART_BTN,
|
||||
LV_BTNMATRIX_PART_BTN_2,
|
||||
};
|
||||
typedef uint8_t lv_btnmatrix_part_t;
|
||||
|
||||
@@ -163,20 +166,20 @@ void lv_btnmatrix_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnmatrix_ctrl_t ctrl);
|
||||
void lv_btnmatrix_set_btn_width(lv_obj_t * btnm, uint16_t btn_id, uint8_t width);
|
||||
|
||||
/**
|
||||
* Make the button matrix like a selector widget (only one button may be toggled at a time).
|
||||
* Make the button matrix like a selector widget (only one button may be checked at a time).
|
||||
* `Checkable` must be enabled on the buttons you want to be selected with `lv_btnmatrix_set_ctrl` or
|
||||
* `lv_btnmatrix_set_btn_ctrl_all`.
|
||||
* @param btnm Button matrix object
|
||||
* @param one_chk Whether "one check" mode is enabled
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param one_chk whether "one check" mode is enabled
|
||||
*/
|
||||
void lv_btnmatrix_set_one_check(lv_obj_t * btnm, bool one_chk);
|
||||
void lv_btnmatrix_set_one_checked(lv_obj_t * btnm, bool one_chk);
|
||||
|
||||
/**
|
||||
* Set the align of the map text (left, right or center)
|
||||
* Set the align of the texts (left, right or center)
|
||||
* @param btnm pointer to a btnmatrix object
|
||||
* @param align LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER
|
||||
*/
|
||||
void lv_btnmatrix_set_align(lv_obj_t * btnm, lv_label_align_t align);
|
||||
void lv_btnmatrix_set_text_align(lv_obj_t * btnm, lv_label_align_t align);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@@ -232,18 +235,18 @@ const char * lv_btnmatrix_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id);
|
||||
* Get the whether a control value is enabled or disabled for button of a button matrix
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param btn_id the index a button not counting new line characters. (E.g. the return value of
|
||||
* lv_btnmatrix_get_pressed/released)
|
||||
* lv_btnmatrix_get_active)
|
||||
* @param ctrl control values to check (ORed value can be used)
|
||||
* @return true: long press repeat is disabled; false: long press repeat enabled
|
||||
*/
|
||||
bool lv_btnmatrix_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl);
|
||||
|
||||
/**
|
||||
* Find whether "one toggle" mode is enabled.
|
||||
* Find whether "one checked" mode is enabled.
|
||||
* @param btnm Button matrix object
|
||||
* @return whether "one toggle" mode is enabled
|
||||
* @return whether "one checked" mode is enabled
|
||||
*/
|
||||
bool lv_btnmatrix_get_one_check(const lv_obj_t * btnm);
|
||||
bool lv_btnmatrix_get_one_checked(const lv_obj_t * btnm);
|
||||
|
||||
/**
|
||||
* Get the align attribute
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
* @file lv_calendar.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_CALENDAR_H
|
||||
#define LV_CALENDAR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_CALENDAR != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Represents a date on the calendar object (platform-agnostic).
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t year;
|
||||
int8_t month;
|
||||
int8_t day;
|
||||
} lv_calendar_date_t;
|
||||
|
||||
/*Data of calendar*/
|
||||
typedef struct {
|
||||
/*None*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_calendar_date_t today; /*Date of today*/
|
||||
lv_calendar_date_t showed_date; /*Currently visible month (day is ignored)*/
|
||||
lv_calendar_date_t * highlighted_dates; /*Apply different style on these days (pointer to an
|
||||
array defined by the user)*/
|
||||
int8_t btn_pressing; /*-1: prev month pressing, +1 next month pressing on the header*/
|
||||
uint16_t highlighted_dates_num; /*Number of elements in `highlighted_days`*/
|
||||
lv_calendar_date_t pressed_date;
|
||||
const char ** day_names; /*Pointer to an array with the name of the days (NULL: use default names)*/
|
||||
const char ** month_names; /*Pointer to an array with the name of the month (NULL. use default names)*/
|
||||
|
||||
/*Styles*/
|
||||
lv_style_list_t style_header;
|
||||
lv_style_list_t style_day_names;
|
||||
lv_style_list_t style_date_nums;
|
||||
} lv_calendar_ext_t;
|
||||
|
||||
/** Calendar parts*/
|
||||
enum {
|
||||
LV_CALENDAR_PART_BG, /**< Background and "normal" date numbers style */
|
||||
LV_CALENDAR_PART_HEADER, /** Calendar header style */
|
||||
LV_CALENDAR_PART_DAY_NAMES, /** Day name style */
|
||||
LV_CALENDAR_PART_DATE, /** Day name style */
|
||||
};
|
||||
typedef uint8_t lv_calendar_part_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a calendar objects
|
||||
* @param par pointer to an object, it will be the parent of the new calendar
|
||||
* @param copy pointer to a calendar object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created calendar
|
||||
*/
|
||||
lv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today);
|
||||
|
||||
/**
|
||||
* Set the currently showed
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value
|
||||
* will be saved it can be local variable too.
|
||||
*/
|
||||
void lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed);
|
||||
|
||||
/**
|
||||
* Set the the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER
|
||||
* WILL BE SAVED! CAN'T BE LOCAL ARRAY.
|
||||
* @param date_num number of dates in the array
|
||||
*/
|
||||
void lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t highlighted[], uint16_t date_num);
|
||||
|
||||
/**
|
||||
* Set the name of the days
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param day_names pointer to an array with the names. E.g. `const char * days[7] = {"Sun", "Mon",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names);
|
||||
|
||||
/**
|
||||
* Set the name of the month
|
||||
* @param calendar pointer to a calendar object
|
||||
* @param month_names pointer to an array with the names. E.g. `const char * days[12] = {"Jan", "Feb",
|
||||
* ...}` Only the pointer will be saved so this variable can't be local which will be destroyed
|
||||
* later.
|
||||
*/
|
||||
void lv_calendar_set_month_names(lv_obj_t * calendar, const char ** month_names);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the today's date
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return return pointer to an `lv_calendar_date_t` variable containing the date of today.
|
||||
*/
|
||||
lv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the currently showed
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to an `lv_calendar_date_t` variable containing the date is being shown.
|
||||
*/
|
||||
lv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the the pressed date.
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to an `lv_calendar_date_t` variable containing the pressed date.
|
||||
* `NULL` if not date pressed (e.g. the header)
|
||||
*/
|
||||
lv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to an `lv_calendar_date_t` array containing the dates.
|
||||
*/
|
||||
lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the number of the highlighted dates
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return number of highlighted days
|
||||
*/
|
||||
uint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the name of the days
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to the array of day names
|
||||
*/
|
||||
const char ** lv_calendar_get_day_names(const lv_obj_t * calendar);
|
||||
|
||||
/**
|
||||
* Get the name of the month
|
||||
* @param calendar pointer to a calendar object
|
||||
* @return pointer to the array of month names
|
||||
*/
|
||||
const char ** lv_calendar_get_month_names(const lv_obj_t * calendar);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CALENDAR_H*/
|
||||
@@ -1108,9 +1108,10 @@ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * par
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(canvas, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
_lv_memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(chart, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(chart, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("chart created");
|
||||
@@ -330,7 +330,7 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)
|
||||
|
||||
if(point_cnt < 1) point_cnt = 1;
|
||||
|
||||
_LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
_LV_LL_READ_BACK(&ext->series_ll, ser) {
|
||||
if(!ser->ext_buf_assigned) {
|
||||
if(ser->start_point != 0) {
|
||||
lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt);
|
||||
@@ -810,12 +810,12 @@ lv_coord_t lv_chart_get_x_from_index(lv_obj_t * chart, lv_chart_series_t * ser,
|
||||
else if(ext->type & LV_CHART_TYPE_COLUMN) {
|
||||
lv_coord_t col_w = w / ((_lv_ll_get_len(&ext->series_ll) + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/
|
||||
lv_chart_series_t * itr_ser = NULL;
|
||||
lv_style_int_t col_space = lv_obj_get_style_pad_inner(chart, LV_CHART_PART_SERIES);
|
||||
lv_style_int_t col_space = lv_obj_get_style_pad_left(chart, LV_CHART_PART_SERIES);
|
||||
|
||||
x = (int32_t)((int32_t)w * id) / ext->point_cnt;
|
||||
x += col_w / 2; /*Start offset*/
|
||||
|
||||
_LV_LL_READ_BACK(ext->series_ll, itr_ser) {
|
||||
_LV_LL_READ_BACK(&ext->series_ll, itr_ser) {
|
||||
if(itr_ser == ser) break;
|
||||
x += col_w;
|
||||
}
|
||||
@@ -947,7 +947,7 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param
|
||||
|
||||
res = ancestor_signal(chart, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
|
||||
@@ -963,9 +963,9 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param
|
||||
}
|
||||
_lv_ll_clear(&ext->series_ll);
|
||||
|
||||
lv_obj_clean_style_list(chart, LV_CHART_PART_SERIES);
|
||||
lv_obj_clean_style_list(chart, LV_CHART_PART_CURSOR);
|
||||
lv_obj_clean_style_list(chart, LV_CHART_PART_SERIES_BG);
|
||||
_lv_obj_reset_style_list_no_refr(chart, LV_CHART_PART_SERIES);
|
||||
_lv_obj_reset_style_list_no_refr(chart, LV_CHART_PART_CURSOR);
|
||||
_lv_obj_reset_style_list_no_refr(chart, LV_CHART_PART_SERIES_BG);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -1134,7 +1134,7 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
|
||||
if(point_radius > line_dsc.width / 2) line_dsc.raw_end = 1;
|
||||
|
||||
/*Go through all data lines*/
|
||||
_LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
_LV_LL_READ_BACK(&ext->series_ll, ser) {
|
||||
line_dsc.color = ser->color;
|
||||
point_dsc.bg_color = ser->color;
|
||||
area_dsc.bg_color = ser->color;
|
||||
@@ -1249,7 +1249,7 @@ static void draw_series_column(lv_obj_t * chart, const lv_area_t * series_area,
|
||||
lv_chart_series_t * ser;
|
||||
lv_coord_t col_w = w / ((_lv_ll_get_len(&ext->series_ll) + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/
|
||||
lv_coord_t x_ofs = col_w / 2; /*Shift with a half col.*/
|
||||
lv_style_int_t col_space = lv_obj_get_style_pad_inner(chart, LV_CHART_PART_SERIES);
|
||||
lv_style_int_t col_space = lv_obj_get_style_pad_left(chart, LV_CHART_PART_SERIES);
|
||||
|
||||
lv_draw_rect_dsc_t col_dsc;
|
||||
lv_draw_rect_dsc_init(&col_dsc);
|
||||
@@ -1270,7 +1270,7 @@ static void draw_series_column(lv_obj_t * chart, const lv_area_t * series_area,
|
||||
x_act += series_area->x1 + x_ofs;
|
||||
|
||||
/*Draw the current point of all data line*/
|
||||
_LV_LL_READ_BACK(ext->series_ll, ser) {
|
||||
_LV_LL_READ_BACK(&ext->series_ll, ser) {
|
||||
lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;
|
||||
|
||||
col_a.x1 = x_act;
|
||||
@@ -1327,7 +1327,7 @@ static void draw_cursors(lv_obj_t * chart, const lv_area_t * series_area, const
|
||||
if(point_radius > line_dsc.width / 2) line_dsc.raw_end = 1;
|
||||
|
||||
/*Go through all cursor lines*/
|
||||
_LV_LL_READ_BACK(ext->cursors_ll, cursor) {
|
||||
_LV_LL_READ_BACK(&ext->cursors_ll, cursor) {
|
||||
line_dsc.color = cursor->color;
|
||||
point_dsc.bg_color = cursor->color;
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ typedef struct {
|
||||
/*Parts of the chart*/
|
||||
enum {
|
||||
LV_CHART_PART_BG = LV_OBJ_PART_MAIN,
|
||||
LV_CHART_PART_SERIES_BG = _LV_OBJ_PART_VIRTUAL_LAST,
|
||||
LV_CHART_PART_SERIES_BG,
|
||||
LV_CHART_PART_SERIES,
|
||||
LV_CHART_PART_CURSOR
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -25,6 +26,7 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_checkbox_signal(lv_obj_t * cb, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type);
|
||||
|
||||
@@ -32,6 +34,7 @@ static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -52,11 +55,12 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
LV_LOG_TRACE("check box create started");
|
||||
|
||||
/*Create the ancestor basic object*/
|
||||
lv_obj_t * cb = lv_btn_create(par, copy);
|
||||
lv_obj_t * cb = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(cb);
|
||||
if(cb == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(cb);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(cb);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_allocate_ext_attr(cb, sizeof(lv_checkbox_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
@@ -65,34 +69,27 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext->bullet = NULL;
|
||||
ext->label = NULL;
|
||||
lv_style_list_init(&ext->style_bullet);
|
||||
|
||||
lv_obj_set_signal_cb(cb, lv_checkbox_signal);
|
||||
lv_obj_set_design_cb(cb, lv_checkbox_design);
|
||||
|
||||
/*Init the new checkbox object*/
|
||||
if(copy == NULL) {
|
||||
ext->bullet = lv_obj_create(cb, NULL);
|
||||
lv_obj_set_click(ext->bullet, false);
|
||||
|
||||
ext->label = lv_label_create(cb, NULL);
|
||||
|
||||
lv_checkbox_set_text(cb, "Check box");
|
||||
lv_btn_set_layout(cb, LV_LAYOUT_ROW_MID);
|
||||
lv_btn_set_fit(cb, LV_FIT_TIGHT);
|
||||
lv_btn_set_checkable(cb, true);
|
||||
lv_obj_add_protect(cb, LV_PROTECT_PRESS_LOST);
|
||||
|
||||
ext->txt = "Check box";
|
||||
ext->static_txt = 1;
|
||||
lv_theme_apply(cb, LV_THEME_CHECKBOX);
|
||||
|
||||
lv_obj_add_flag(cb, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_add_flag(cb, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_set_size(cb, LV_SIZE_AUTO, LV_SIZE_AUTO);
|
||||
}
|
||||
else {
|
||||
|
||||
lv_checkbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->bullet = lv_obj_create(cb, copy_ext->bullet);
|
||||
ext->label = lv_label_create(cb, copy_ext->label);
|
||||
lv_style_list_copy(&ext->style_bullet, ©_ext->style_bullet);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
// lv_obj_refresh_style(cb);
|
||||
_lv_obj_refresh_style(cb, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("check box created");
|
||||
@@ -112,10 +109,16 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
*/
|
||||
void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
|
||||
{
|
||||
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_label_set_text(ext->label, txt);
|
||||
size_t len = strlen(txt);
|
||||
|
||||
if(!ext->static_txt) ext->txt = lv_mem_realloc(ext->txt, len + 1);
|
||||
else ext->txt = lv_mem_alloc(len + 1);
|
||||
|
||||
strcpy(ext->txt, txt);
|
||||
ext->static_txt = 0;
|
||||
|
||||
_lv_obj_handle_self_size_chg(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,10 +129,14 @@ void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
|
||||
*/
|
||||
void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
|
||||
{
|
||||
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_label_set_text_static(ext->label, txt);
|
||||
|
||||
if(!ext->static_txt) lv_mem_free(ext->txt);
|
||||
|
||||
ext->txt = txt;
|
||||
ext->static_txt = 1;
|
||||
|
||||
_lv_obj_handle_self_size_chg(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,62 +146,21 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
|
||||
*/
|
||||
void lv_checkbox_set_checked(lv_obj_t * cb, bool checked)
|
||||
{
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_btn_set_state(cb, checked ? LV_BTN_STATE_CHECKED_RELEASED : LV_BTN_STATE_RELEASED);
|
||||
|
||||
if(checked) {
|
||||
lv_obj_add_state(ext->bullet, LV_STATE_CHECKED);
|
||||
lv_obj_add_state(ext->label, LV_STATE_CHECKED);
|
||||
}
|
||||
else {
|
||||
lv_obj_clear_state(ext->bullet, LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(ext->label, LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
lv_obj_clear_state(ext->bullet, LV_STATE_DISABLED);
|
||||
lv_obj_clear_state(ext->label, LV_STATE_DISABLED);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG);
|
||||
lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN);
|
||||
#endif
|
||||
if(checked) lv_obj_set_state(cb, LV_STATE_CHECKED);
|
||||
else lv_obj_clear_state(cb, LV_STATE_CHECKED);
|
||||
_lv_obj_remove_style_trans(cb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make the check box inactive (disabled)
|
||||
* @param cb pointer to a check box object
|
||||
* @param dis true; make the checkbox disabled; false: make the chackbox active
|
||||
*/
|
||||
void lv_checkbox_set_disabled(lv_obj_t * cb)
|
||||
void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis)
|
||||
{
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_btn_set_state(cb, LV_BTN_STATE_DISABLED);
|
||||
|
||||
lv_obj_add_state(ext->bullet, LV_STATE_DISABLED);
|
||||
lv_obj_add_state(ext->label, LV_STATE_DISABLED);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG);
|
||||
lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of a check box
|
||||
* @param cb pointer to a check box object
|
||||
* @param state the new state of the check box (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state)
|
||||
{
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
lv_btn_set_state(cb, state);
|
||||
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
|
||||
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG);
|
||||
lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN);
|
||||
#endif
|
||||
if(dis) lv_obj_set_state(cb, LV_STATE_DISABLED);
|
||||
else lv_obj_clear_state(cb, LV_STATE_DISABLED);
|
||||
_lv_obj_remove_style_trans(cb);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@@ -208,16 +174,86 @@ void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state)
|
||||
*/
|
||||
const char * lv_checkbox_get_text(const lv_obj_t * cb)
|
||||
{
|
||||
LV_ASSERT_OBJ(cb, LV_OBJX_NAME);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
return lv_label_get_text(ext->label);
|
||||
return ext->txt;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the check box
|
||||
* @param cb pointer to a check box object
|
||||
* @param clip_area 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 an element of `lv_design_res_t`
|
||||
*/
|
||||
static lv_design_res_t lv_checkbox_design(lv_obj_t * cb, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
{
|
||||
/* A label never covers an area */
|
||||
if(mode == LV_DESIGN_COVER_CHK)
|
||||
return LV_DESIGN_RES_NOT_COVER;
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/*Draw the background*/
|
||||
ancestor_design(cb, clip_area, mode);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_CHECKBOX_PART_MAIN);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
|
||||
lv_coord_t bg_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_MAIN);
|
||||
lv_coord_t bg_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_MAIN);
|
||||
|
||||
lv_coord_t bullet_leftm = lv_obj_get_style_margin_left(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_topm = lv_obj_get_style_margin_top(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_rightm = lv_obj_get_style_margin_right(cb, LV_CHECKBOX_PART_BULLET);
|
||||
|
||||
lv_coord_t bullet_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
|
||||
|
||||
lv_draw_rect_dsc_t bullet_dsc;
|
||||
lv_draw_rect_dsc_init(&bullet_dsc);
|
||||
lv_obj_init_draw_rect_dsc(cb, LV_CHECKBOX_PART_BULLET, &bullet_dsc);
|
||||
lv_area_t bullet_area;
|
||||
bullet_area.x1 = cb->coords.x1 + bg_leftp + bullet_leftm;
|
||||
bullet_area.x2 = bullet_area.x1 + font_h + bullet_leftp + bullet_rightp - 1;
|
||||
bullet_area.y1 = cb->coords.y1 + bg_topp + bullet_topm;
|
||||
bullet_area.y2 = bullet_area.y1 + font_h + bullet_topp + bullet_bottomp - 1;
|
||||
|
||||
lv_draw_rect(&bullet_area, clip_area, &bullet_dsc);
|
||||
|
||||
lv_coord_t line_space = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
|
||||
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
|
||||
|
||||
lv_point_t txt_size;
|
||||
_lv_txt_get_size(&txt_size, ext->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
|
||||
lv_draw_label_dsc_t txt_dsc;
|
||||
lv_draw_label_dsc_init(&txt_dsc);
|
||||
lv_obj_init_draw_label_dsc(cb, LV_CHECKBOX_PART_MAIN, &txt_dsc);
|
||||
|
||||
lv_coord_t y_ofs = (lv_area_get_height(&bullet_area) - font_h) / 2;
|
||||
lv_area_t txt_area;
|
||||
txt_area.x1 = bullet_area.x2 + bullet_rightm;
|
||||
txt_area.x2 = txt_area.x1 + txt_size.x;
|
||||
txt_area.y1 = cb->coords.y1 + bg_topp + y_ofs;
|
||||
txt_area.y2 = txt_area.y1 + txt_size.y;
|
||||
|
||||
lv_draw_label(&txt_area, clip_area, &txt_dsc, ext->txt, NULL);
|
||||
|
||||
} else {
|
||||
ancestor_design(cb, clip_area, mode);
|
||||
}
|
||||
|
||||
return LV_DESIGN_RES_OK;
|
||||
}
|
||||
/**
|
||||
* Signal function of the check box
|
||||
* @param cb pointer to a check box object
|
||||
@@ -228,43 +264,46 @@ const char * lv_checkbox_get_text(const lv_obj_t * cb)
|
||||
static lv_res_t lv_checkbox_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(cb, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_checkbox_get_style(cb, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(cb, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(cb, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(ext->label, LV_LABEL_PART_MAIN);
|
||||
lv_coord_t line_height = lv_font_get_line_height(font);
|
||||
lv_coord_t leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
|
||||
|
||||
lv_obj_set_size(ext->bullet, line_height + leftp + rightp, line_height + topp + bottomp);
|
||||
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
|
||||
else if (sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST ||
|
||||
sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
#if LV_USE_GROUP
|
||||
char c = *((char *)param);
|
||||
if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN || c == LV_KEY_LEFT || c == LV_KEY_UP) {
|
||||
/*Follow the backgrounds state with the bullet*/
|
||||
lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG));
|
||||
}
|
||||
#endif
|
||||
else if (sign == LV_SIGNAL_GET_SELF_SIZE) {
|
||||
lv_point_t * p = param;
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_CHECKBOX_PART_MAIN);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_coord_t line_space = lv_obj_get_style_text_line_space(cb, LV_CHECKBOX_PART_MAIN);
|
||||
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(cb, LV_CHECKBOX_PART_MAIN);
|
||||
|
||||
lv_point_t txt_size;
|
||||
_lv_txt_get_size(&txt_size, ext->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
|
||||
lv_coord_t bullet_leftm = lv_obj_get_style_margin_left(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_topm = lv_obj_get_style_margin_top(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_rightm = lv_obj_get_style_margin_right(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_bottomm = lv_obj_get_style_margin_bottom(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_leftp = lv_obj_get_style_pad_left(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_rightp = lv_obj_get_style_pad_right(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_topp = lv_obj_get_style_pad_top(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_coord_t bullet_bottomp = lv_obj_get_style_pad_bottom(cb, LV_CHECKBOX_PART_BULLET);
|
||||
lv_point_t bullet_size;
|
||||
bullet_size.x = font_h + bullet_leftm + bullet_rightm + bullet_leftp + bullet_rightp;
|
||||
bullet_size.y = font_h + bullet_topm + bullet_bottomm + bullet_topp + bullet_bottomp;
|
||||
|
||||
p->x = bullet_size.x + txt_size.x;
|
||||
p->y = LV_MATH_MAX(bullet_size.y, txt_size.y);
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -277,11 +316,11 @@ static lv_style_list_t * lv_checkbox_get_style(lv_obj_t * cb, uint8_t type)
|
||||
|
||||
lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb);
|
||||
switch(type) {
|
||||
case LV_CHECKBOX_PART_BG:
|
||||
case LV_CHECKBOX_PART_MAIN:
|
||||
style_dsc_p = &cb->style_list;
|
||||
break;
|
||||
case LV_CHECKBOX_PART_BULLET:
|
||||
style_dsc_p = lv_obj_get_style_list(ext->bullet, LV_BTN_PART_MAIN);
|
||||
style_dsc_p = &ext->style_bullet;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
|
||||
@@ -14,22 +14,15 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
#if LV_USE_CHECKBOX != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_BTN == 0
|
||||
#error "lv_cb: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL == 0
|
||||
#error "lv_cb: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_btn.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@@ -40,18 +33,17 @@ extern "C" {
|
||||
|
||||
/*Data of check box*/
|
||||
typedef struct {
|
||||
lv_btn_ext_t bg_btn; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t * bullet; /*Pointer to button*/
|
||||
lv_obj_t * label; /*Pointer to label*/
|
||||
/*New data for this widget */
|
||||
lv_style_list_t style_bullet;
|
||||
char * txt;
|
||||
uint32_t static_txt :1;
|
||||
} lv_checkbox_ext_t;
|
||||
|
||||
/** Checkbox styles. */
|
||||
enum {
|
||||
LV_CHECKBOX_PART_BG = LV_BTN_PART_MAIN, /**< Style of object background. */
|
||||
LV_CHECKBOX_PART_MAIN = LV_OBJ_PART_MAIN, /**< Style of object background. */
|
||||
LV_CHECKBOX_PART_BULLET, /**< Style of the bullet */
|
||||
_LV_CHECKBOX_PART_VIRTUAL_LAST,
|
||||
LV_CHECKBOX_PART_BULLET = _LV_BTN_PART_REAL_LAST, /**< Style of box (released). */
|
||||
_LV_CHECKBOX_PART_REAL_LAST
|
||||
};
|
||||
typedef uint8_t lv_checkbox_style_t;
|
||||
|
||||
@@ -71,22 +63,6 @@ lv_obj_t * lv_checkbox_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the text of a check box. `txt` will be copied and may be deallocated
|
||||
* after this function returns.
|
||||
* @param cb pointer to a check box
|
||||
* @param txt the text of the check box. NULL to refresh with the current text.
|
||||
*/
|
||||
void lv_checkbox_set_text(lv_obj_t * cb, const char * txt);
|
||||
|
||||
/**
|
||||
* Set the text of a check box. `txt` must not be deallocated during the life
|
||||
* of this checkbox.
|
||||
* @param cb pointer to a check box
|
||||
* @param txt the text of the check box. NULL to refresh with the current text.
|
||||
*/
|
||||
void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt);
|
||||
|
||||
/**
|
||||
* Set the state of the check box
|
||||
* @param cb pointer to a check box object
|
||||
@@ -97,26 +73,14 @@ void lv_checkbox_set_checked(lv_obj_t * cb, bool checked);
|
||||
/**
|
||||
* Make the check box inactive (disabled)
|
||||
* @param cb pointer to a check box object
|
||||
* @param dis true; make the checkbox disabled; false: make the checkbox active
|
||||
*/
|
||||
void lv_checkbox_set_disabled(lv_obj_t * cb);
|
||||
void lv_checkbox_set_disabled(lv_obj_t * cb, bool dis);
|
||||
|
||||
/**
|
||||
* Set the state of a check box
|
||||
* @param cb pointer to a check box object
|
||||
* @param state the new state of the check box (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state);
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the text of a check box
|
||||
* @param cb pointer to check box object
|
||||
* @return pointer to the text of the check box
|
||||
*/
|
||||
const char * lv_checkbox_get_text(const lv_obj_t * cb);
|
||||
|
||||
/**
|
||||
* Get the current state of the check box
|
||||
* @param cb pointer to a check box object
|
||||
@@ -124,7 +88,7 @@ const char * lv_checkbox_get_text(const lv_obj_t * cb);
|
||||
*/
|
||||
static inline bool lv_checkbox_is_checked(const lv_obj_t * cb)
|
||||
{
|
||||
return lv_btn_get_state(cb) == LV_BTN_STATE_RELEASED ? false : true;
|
||||
return lv_obj_get_state(cb) & LV_STATE_CHECKED ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,19 +96,9 @@ static inline bool lv_checkbox_is_checked(const lv_obj_t * cb)
|
||||
* @param cb pointer to a check box object
|
||||
* @return true: inactive; false: not inactive
|
||||
*/
|
||||
static inline bool lv_checkbox_is_inactive(const lv_obj_t * cb)
|
||||
static inline bool lv_checkbox_is_disabled(const lv_obj_t * cb)
|
||||
{
|
||||
return lv_btn_get_state(cb) == LV_BTN_STATE_DISABLED ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of a check box
|
||||
* @param cb pointer to a check box object
|
||||
* @return the state of the check box (from lv_btn_state_t enum)
|
||||
*/
|
||||
static inline lv_btn_state_t lv_checkbox_get_state(const lv_obj_t * cb)
|
||||
{
|
||||
return lv_btn_get_state(cb);
|
||||
return lv_obj_get_state(cb) & LV_STATE_DISABLED ? true : false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -1,805 +0,0 @@
|
||||
/**
|
||||
* @file lv_cont.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_cont.h"
|
||||
#if LV_USE_CONT != 0
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_draw/lv_draw_mask.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_cont"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_cont_get_style(lv_obj_t * cont, uint8_t type);
|
||||
static void lv_cont_refr_layout(lv_obj_t * cont);
|
||||
static void lv_cont_layout_col(lv_obj_t * cont);
|
||||
static void lv_cont_layout_row(lv_obj_t * cont);
|
||||
static void lv_cont_layout_center(lv_obj_t * cont);
|
||||
static void lv_cont_layout_pretty(lv_obj_t * cont);
|
||||
static void lv_cont_layout_grid(lv_obj_t * cont);
|
||||
static void lv_cont_refr_autofit(lv_obj_t * cont);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a container objects
|
||||
* @param par pointer to an object, it will be the parent of the new container
|
||||
* @param copy pointer to a container object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created container
|
||||
*/
|
||||
lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
|
||||
LV_LOG_TRACE("container create started");
|
||||
|
||||
/*Create a basic object*/
|
||||
lv_obj_t * cont = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(cont);
|
||||
if(cont == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(cont);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(cont);
|
||||
|
||||
lv_obj_allocate_ext_attr(cont, sizeof(lv_cont_ext_t));
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(cont);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LV_ASSERT_MEM(ext);
|
||||
ext->fit_left = LV_FIT_NONE;
|
||||
ext->fit_right = LV_FIT_NONE;
|
||||
ext->fit_top = LV_FIT_NONE;
|
||||
ext->fit_bottom = LV_FIT_NONE;
|
||||
ext->layout = LV_LAYOUT_OFF;
|
||||
|
||||
lv_obj_set_signal_cb(cont, lv_cont_signal);
|
||||
|
||||
/*Init the new container*/
|
||||
if(copy == NULL) {
|
||||
/*Set the default styles if it's not screen*/
|
||||
if(par != NULL) {
|
||||
lv_theme_apply(cont, LV_THEME_CONT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*Copy an existing object*/
|
||||
else {
|
||||
lv_cont_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->fit_left = copy_ext->fit_left;
|
||||
ext->fit_right = copy_ext->fit_right;
|
||||
ext->fit_top = copy_ext->fit_top;
|
||||
ext->fit_bottom = copy_ext->fit_bottom;
|
||||
ext->layout = copy_ext->layout;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(cont, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("container created");
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set a layout on a container
|
||||
* @param cont pointer to a container object
|
||||
* @param layout a layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
if(ext->layout == layout) return;
|
||||
|
||||
ext->layout = layout;
|
||||
|
||||
/*Send a signal to refresh the layout*/
|
||||
cont->signal_cb(cont, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 directions separately.
|
||||
* It tell how to change the container's size automatically.
|
||||
* @param cont pointer to a container object
|
||||
* @param left left fit policy from `lv_fit_t`
|
||||
* @param right right fit policy from `lv_fit_t`
|
||||
* @param top bottom fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_invalidate(cont);
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
if(ext->fit_left == left && ext->fit_right == right && ext->fit_top == top && ext->fit_bottom == bottom) {
|
||||
return;
|
||||
}
|
||||
|
||||
ext->fit_left = left;
|
||||
ext->fit_right = right;
|
||||
ext->fit_top = top;
|
||||
ext->fit_bottom = bottom;
|
||||
|
||||
/*Send a signal to refresh the layout*/
|
||||
cont->signal_cb(cont, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the layout of a container
|
||||
* @param cont pointer to container object
|
||||
* @return the layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
lv_layout_t lv_cont_get_layout(const lv_obj_t * cont)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
return ext->layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get left fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
return ext->fit_left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get right fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
return ext->fit_right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
return ext->fit_top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bottom fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont)
|
||||
{
|
||||
LV_ASSERT_OBJ(cont, LV_OBJX_NAME);
|
||||
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
return ext->fit_bottom;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the container
|
||||
* @param cont pointer to a container object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
|
||||
{
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_cont_get_style(cont, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(cont, sign, param);
|
||||
}
|
||||
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(cont, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/
|
||||
lv_cont_refr_layout(cont);
|
||||
lv_cont_refr_autofit(cont);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
||||
lv_cont_refr_layout(cont);
|
||||
lv_cont_refr_autofit(cont);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
if(lv_obj_get_width(cont) != lv_area_get_width(param) || lv_obj_get_height(cont) != lv_area_get_height(param)) {
|
||||
lv_cont_refr_layout(cont);
|
||||
lv_cont_refr_autofit(cont);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) {
|
||||
/*MAX and EDGE fit needs to be refreshed if the parent's size has changed*/
|
||||
lv_cont_refr_autofit(cont);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static lv_style_list_t * lv_cont_get_style(lv_obj_t * cont, uint8_t type)
|
||||
{
|
||||
lv_style_list_t * style_dsc_p;
|
||||
switch(type) {
|
||||
case LV_CONT_PART_MAIN:
|
||||
style_dsc_p = &cont->style_list;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
}
|
||||
|
||||
return style_dsc_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the layout of a container
|
||||
* @param cont pointer to an object which layout should be refreshed
|
||||
*/
|
||||
static void lv_cont_refr_layout(lv_obj_t * cont)
|
||||
{
|
||||
if(lv_obj_is_protected(cont, LV_PROTECT_CHILD_CHG)) return;
|
||||
lv_layout_t type = lv_cont_get_layout(cont);
|
||||
|
||||
/*'cont' has to be at least 1 child*/
|
||||
if(lv_obj_get_child(cont, NULL) == NULL) return;
|
||||
|
||||
if(type == LV_LAYOUT_OFF) return;
|
||||
|
||||
if(type == LV_LAYOUT_CENTER) {
|
||||
lv_cont_layout_center(cont);
|
||||
}
|
||||
else if(type == LV_LAYOUT_COLUMN_LEFT || type == LV_LAYOUT_COLUMN_MID || type == LV_LAYOUT_COLUMN_RIGHT) {
|
||||
lv_cont_layout_col(cont);
|
||||
}
|
||||
else if(type == LV_LAYOUT_ROW_TOP || type == LV_LAYOUT_ROW_MID || type == LV_LAYOUT_ROW_BOTTOM) {
|
||||
lv_cont_layout_row(cont);
|
||||
}
|
||||
else if(type == LV_LAYOUT_PRETTY_MID || type == LV_LAYOUT_PRETTY_TOP || type == LV_LAYOUT_PRETTY_BOTTOM) {
|
||||
lv_cont_layout_pretty(cont);
|
||||
}
|
||||
else if(type == LV_LAYOUT_GRID) {
|
||||
lv_cont_layout_grid(cont);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle column type layouts
|
||||
* @param cont pointer to an object which layout should be handled
|
||||
*/
|
||||
static void lv_cont_layout_col(lv_obj_t * cont)
|
||||
{
|
||||
lv_coord_t left = lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t right = lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t top = lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t inner = lv_obj_get_style_pad_inner(cont, LV_CONT_PART_MAIN);
|
||||
|
||||
lv_layout_t type = lv_cont_get_layout(cont);
|
||||
lv_obj_t * child;
|
||||
|
||||
/*Adjust margin and get the alignment type*/
|
||||
lv_align_t align;
|
||||
lv_coord_t hpad_corr;
|
||||
|
||||
switch(type) {
|
||||
case LV_LAYOUT_COLUMN_LEFT:
|
||||
hpad_corr = left;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
case LV_LAYOUT_COLUMN_MID:
|
||||
hpad_corr = 0;
|
||||
align = LV_ALIGN_IN_TOP_MID;
|
||||
break;
|
||||
case LV_LAYOUT_COLUMN_RIGHT:
|
||||
hpad_corr = -right;
|
||||
align = LV_ALIGN_IN_TOP_RIGHT;
|
||||
break;
|
||||
default:
|
||||
hpad_corr = 0;
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
lv_obj_add_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord = top;
|
||||
_LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(child, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(child, LV_OBJ_PART_MAIN);
|
||||
lv_obj_align(child, cont, align, hpad_corr + mleft, last_cord + mtop);
|
||||
last_cord += lv_obj_get_height(child) + inner + mtop + mbottom;
|
||||
}
|
||||
|
||||
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle row type layouts
|
||||
* @param cont pointer to an object which layout should be handled
|
||||
*/
|
||||
static void lv_cont_layout_row(lv_obj_t * cont)
|
||||
{
|
||||
|
||||
lv_layout_t type = lv_cont_get_layout(cont);
|
||||
lv_obj_t * child;
|
||||
|
||||
/*Adjust margin and get the alignment type*/
|
||||
lv_align_t align;
|
||||
lv_coord_t vpad_corr;
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(cont);
|
||||
switch(type) {
|
||||
case LV_LAYOUT_ROW_TOP:
|
||||
vpad_corr = lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_TOP_RIGHT : LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
case LV_LAYOUT_ROW_MID:
|
||||
vpad_corr = 0;
|
||||
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_RIGHT_MID : LV_ALIGN_IN_LEFT_MID;
|
||||
break;
|
||||
case LV_LAYOUT_ROW_BOTTOM:
|
||||
vpad_corr = -lv_obj_get_style_pad_bottom(cont, LV_CONT_PART_MAIN);
|
||||
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_BOTTOM_RIGHT : LV_ALIGN_IN_BOTTOM_LEFT;
|
||||
break;
|
||||
default:
|
||||
vpad_corr = 0;
|
||||
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_TOP_RIGHT : LV_ALIGN_IN_TOP_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
lv_obj_add_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord;
|
||||
if(base_dir == LV_BIDI_DIR_RTL) last_cord = lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
else last_cord = lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
|
||||
lv_coord_t inner = lv_obj_get_style_pad_inner(cont, LV_CONT_PART_MAIN);
|
||||
|
||||
_LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
|
||||
if(base_dir == LV_BIDI_DIR_RTL) lv_obj_align(child, cont, align, -last_cord, vpad_corr);
|
||||
else lv_obj_align(child, cont, align, last_cord, vpad_corr);
|
||||
|
||||
last_cord += lv_obj_get_width(child) + inner;
|
||||
}
|
||||
|
||||
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the center layout
|
||||
* @param cont pointer to an object which layout should be handled
|
||||
*/
|
||||
static void lv_cont_layout_center(lv_obj_t * cont)
|
||||
{
|
||||
lv_obj_t * child;
|
||||
uint32_t obj_num = 0;
|
||||
lv_coord_t h_tot = 0;
|
||||
|
||||
lv_coord_t inner = lv_obj_get_style_pad_inner(cont, LV_CONT_PART_MAIN);
|
||||
_LV_LL_READ(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
h_tot += lv_obj_get_height(child) + inner;
|
||||
obj_num++;
|
||||
}
|
||||
|
||||
if(obj_num == 0) return;
|
||||
|
||||
h_tot -= inner;
|
||||
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
lv_obj_add_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/* Align the children */
|
||||
lv_coord_t last_cord = -(h_tot / 2);
|
||||
_LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
|
||||
lv_obj_align(child, cont, LV_ALIGN_CENTER, 0, last_cord + lv_obj_get_height(child) / 2);
|
||||
last_cord += lv_obj_get_height(child) + inner;
|
||||
}
|
||||
|
||||
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the pretty layout. Put as many object as possible in row
|
||||
* then begin a new row
|
||||
* @param cont pointer to an object which layout should be handled
|
||||
*/
|
||||
static void lv_cont_layout_pretty(lv_obj_t * cont)
|
||||
{
|
||||
lv_layout_t type = lv_cont_get_layout(cont);
|
||||
|
||||
lv_obj_t * child_rs; /* Row starter child */
|
||||
lv_obj_t * child_rc; /* Row closer child */
|
||||
lv_obj_t * child_tmp; /* Temporary child */
|
||||
lv_coord_t w_obj = lv_obj_get_width(cont);
|
||||
lv_coord_t act_y = lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
|
||||
child_rs = _lv_ll_get_tail(&cont->child_ll); /*Set the row starter child*/
|
||||
if(child_rs == NULL) return; /*Return if no child*/
|
||||
|
||||
lv_obj_add_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
lv_coord_t pleft = lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t pright = lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t pinner = lv_obj_get_style_pad_inner(cont, LV_CONT_PART_MAIN);
|
||||
|
||||
child_rc = child_rs; /*Initially the the row starter and closer is the same*/
|
||||
while(child_rs != NULL) {
|
||||
lv_coord_t h_row = 0;
|
||||
lv_coord_t w_row = pleft + pright; /*The width is at least the left+right pad*/
|
||||
uint32_t obj_num = 0;
|
||||
|
||||
/*Find the row closer object and collect some data*/
|
||||
do {
|
||||
if(lv_obj_get_hidden(child_rc) == false && lv_obj_is_protected(child_rc, LV_PROTECT_POS) == false) {
|
||||
/*If this object is already not fit then break*/
|
||||
lv_coord_t w = lv_obj_get_width(child_rc);
|
||||
w += lv_obj_get_style_margin_left(child_rc, LV_OBJ_PART_MAIN);
|
||||
w += lv_obj_get_style_margin_right(child_rc, LV_OBJ_PART_MAIN);
|
||||
if(w_row + w > w_obj) {
|
||||
/*Step back one child because the last already not fit, so the previous is the
|
||||
* closer*/
|
||||
if(child_rc != NULL && obj_num != 0) {
|
||||
child_rc = _lv_ll_get_next(&cont->child_ll, child_rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
w_row += w + pinner; /*Add the object width + inner padding*/
|
||||
|
||||
lv_coord_t h = lv_obj_get_height(child_rc);
|
||||
h += lv_obj_get_style_margin_top(child_rc, LV_OBJ_PART_MAIN);
|
||||
h += lv_obj_get_style_margin_bottom(child_rc, LV_OBJ_PART_MAIN);
|
||||
h_row = LV_MATH_MAX(h_row, h); /*Search the highest object*/
|
||||
obj_num++;
|
||||
if(lv_obj_is_protected(child_rc, LV_PROTECT_FOLLOW))
|
||||
break; /*If can not be followed by an other object then break here*/
|
||||
}
|
||||
child_rc = _lv_ll_get_prev(&cont->child_ll, child_rc); /*Load the next object*/
|
||||
if(obj_num == 0)
|
||||
child_rs = child_rc; /*If the first object was hidden (or too long) then set the
|
||||
next as first */
|
||||
} while(child_rc != NULL);
|
||||
|
||||
/*If the object is too long then align it to the middle*/
|
||||
if(obj_num == 0) {
|
||||
if(child_rc != NULL) {
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(child_rc, LV_OBJ_PART_MAIN);
|
||||
|
||||
lv_obj_align(child_rc, cont, LV_ALIGN_IN_TOP_MID, 0, act_y + mtop);
|
||||
h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
|
||||
h_row += mtop;
|
||||
h_row += lv_obj_get_style_margin_bottom(child_rc, LV_OBJ_PART_MAIN);
|
||||
}
|
||||
}
|
||||
/*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 + lv_obj_get_style_margin_top(child_rs, LV_OBJ_PART_MAIN));
|
||||
}
|
||||
/* Align the children (from child_rs to child_rc)*/
|
||||
else {
|
||||
w_row -= pinner * obj_num;
|
||||
lv_coord_t new_pinner = (w_obj - w_row) / (obj_num - 1);
|
||||
lv_coord_t act_x = pleft; /*x init*/
|
||||
child_tmp = child_rs;
|
||||
lv_align_t align;
|
||||
int32_t inv;
|
||||
if(lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL) {
|
||||
align = LV_ALIGN_IN_TOP_RIGHT;
|
||||
inv = -1;
|
||||
}
|
||||
else {
|
||||
align = LV_ALIGN_IN_TOP_LEFT;
|
||||
inv = 1;
|
||||
}
|
||||
while(child_tmp != NULL) {
|
||||
if(lv_obj_get_hidden(child_tmp) == false && lv_obj_is_protected(child_tmp, LV_PROTECT_POS) == false) {
|
||||
lv_coord_t mleft = lv_obj_get_style_margin_left(child_tmp, LV_OBJ_PART_MAIN);
|
||||
lv_coord_t mright = lv_obj_get_style_margin_right(child_tmp, LV_OBJ_PART_MAIN);
|
||||
switch(type) {
|
||||
case LV_LAYOUT_PRETTY_TOP:
|
||||
lv_obj_align(child_tmp, cont, align,
|
||||
inv * (act_x + mleft),
|
||||
act_y + lv_obj_get_style_margin_top(child_tmp, LV_OBJ_PART_MAIN));
|
||||
break;
|
||||
case LV_LAYOUT_PRETTY_MID:
|
||||
lv_obj_align(child_tmp, cont, align,
|
||||
inv * (act_x + mleft),
|
||||
act_y + (h_row - lv_obj_get_height(child_tmp)) / 2);
|
||||
|
||||
break;
|
||||
case LV_LAYOUT_PRETTY_BOTTOM:
|
||||
lv_obj_align(child_tmp, cont, align,
|
||||
inv * (act_x + mleft),
|
||||
act_y + h_row - lv_obj_get_height(child_tmp) - lv_obj_get_style_margin_bottom(child_tmp, LV_OBJ_PART_MAIN));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
act_x += lv_obj_get_width(child_tmp) + new_pinner + mleft + mright;
|
||||
}
|
||||
if(child_tmp == child_rc) break;
|
||||
child_tmp = _lv_ll_get_prev(&cont->child_ll, child_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if(child_rc == NULL) break;
|
||||
act_y += pinner + h_row; /*y increment*/
|
||||
child_rs = _lv_ll_get_prev(&cont->child_ll, child_rc); /*Go to the next object*/
|
||||
child_rc = child_rs;
|
||||
}
|
||||
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the grid layout. Align same-sized objects in a grid
|
||||
* @param cont pointer to an object which layout should be handled
|
||||
*/
|
||||
static void lv_cont_layout_grid(lv_obj_t * cont)
|
||||
{
|
||||
lv_coord_t w_fit = lv_obj_get_width_fit(cont);
|
||||
lv_coord_t inner = lv_obj_get_style_pad_inner(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t y_ofs = inner + lv_obj_get_height(lv_obj_get_child(cont, NULL));
|
||||
|
||||
/* Disable child change action because the children will be moved a lot
|
||||
* an unnecessary child change signals could be sent*/
|
||||
lv_obj_add_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/* Align the children */
|
||||
lv_coord_t left = lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
lv_coord_t act_x = left;
|
||||
lv_coord_t act_y = lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
lv_obj_t * child;
|
||||
_LV_LL_READ_BACK(cont->child_ll, child) {
|
||||
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
|
||||
lv_coord_t obj_w = lv_obj_get_width(child);
|
||||
if(act_x + obj_w > w_fit + left) {
|
||||
act_x = left;
|
||||
act_y += y_ofs;
|
||||
}
|
||||
|
||||
lv_obj_set_pos(child, act_x, act_y);
|
||||
act_x += inner + obj_w;
|
||||
}
|
||||
|
||||
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle auto fit. Set the size of the object to involve all children.
|
||||
* @param cont pointer to an object which size will be modified
|
||||
*/
|
||||
static void lv_cont_refr_autofit(lv_obj_t * cont)
|
||||
{
|
||||
if(lv_obj_is_protected(cont, LV_PROTECT_CHILD_CHG)) return;
|
||||
lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);
|
||||
|
||||
if(ext->fit_left == LV_FIT_NONE && ext->fit_right == LV_FIT_NONE && ext->fit_top == LV_FIT_NONE &&
|
||||
ext->fit_bottom == LV_FIT_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t tight_area;
|
||||
lv_area_t ori;
|
||||
lv_obj_t * child_i;
|
||||
|
||||
lv_obj_t * par = lv_obj_get_parent(cont);
|
||||
lv_area_t parent_area;
|
||||
lv_area_copy(&parent_area, &par->coords);
|
||||
parent_area.x1 += lv_obj_get_style_pad_left(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.x2 -= lv_obj_get_style_pad_right(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y1 += lv_obj_get_style_pad_top(par, LV_OBJ_PART_MAIN);
|
||||
parent_area.y2 -= lv_obj_get_style_pad_bottom(par, LV_OBJ_PART_MAIN);
|
||||
|
||||
/*Search the side coordinates of the children*/
|
||||
lv_obj_get_coords(cont, &ori);
|
||||
lv_obj_get_coords(cont, &tight_area);
|
||||
|
||||
bool has_children = _lv_ll_is_empty(&cont->child_ll) ? false : true;
|
||||
|
||||
if(has_children) {
|
||||
tight_area.x1 = LV_COORD_MAX;
|
||||
tight_area.y1 = LV_COORD_MAX;
|
||||
tight_area.x2 = LV_COORD_MIN;
|
||||
tight_area.y2 = LV_COORD_MIN;
|
||||
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
if(lv_obj_get_hidden(child_i) != false) continue;
|
||||
|
||||
if(ext->fit_left != LV_FIT_PARENT) {
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x1 = LV_MATH_MIN(tight_area.x1, child_i->coords.x1 - mleft);
|
||||
}
|
||||
|
||||
if(ext->fit_right != LV_FIT_PARENT) {
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.x2 = LV_MATH_MAX(tight_area.x2, child_i->coords.x2 + mright);
|
||||
}
|
||||
|
||||
if(ext->fit_top != LV_FIT_PARENT) {
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y1 = LV_MATH_MIN(tight_area.y1, child_i->coords.y1 - mtop);
|
||||
}
|
||||
|
||||
if(ext->fit_bottom != LV_FIT_PARENT) {
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(child_i, LV_OBJ_PART_MAIN);
|
||||
tight_area.y2 = LV_MATH_MAX(tight_area.y2, child_i->coords.y2 + mbottom);
|
||||
}
|
||||
}
|
||||
|
||||
tight_area.x1 -= lv_obj_get_style_pad_left(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.x2 += lv_obj_get_style_pad_right(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y1 -= lv_obj_get_style_pad_top(cont, LV_CONT_PART_MAIN);
|
||||
tight_area.y2 += lv_obj_get_style_pad_bottom(cont, LV_CONT_PART_MAIN);
|
||||
}
|
||||
|
||||
lv_area_t new_area;
|
||||
lv_area_copy(&new_area, &ori);
|
||||
|
||||
switch(ext->fit_left) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x1 = tight_area.x1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x1 = parent_area.x1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, parent_area.x1) : parent_area.x1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_right) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.x2 = tight_area.x2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.x2 = parent_area.x2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, parent_area.x2) : parent_area.x2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_top) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y1 = tight_area.y1;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y1 = parent_area.y1;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, parent_area.y1) : parent_area.y1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ext->fit_bottom) {
|
||||
case LV_FIT_TIGHT:
|
||||
new_area.y2 = tight_area.y2;
|
||||
break;
|
||||
case LV_FIT_PARENT:
|
||||
new_area.y2 = parent_area.y2;
|
||||
break;
|
||||
case LV_FIT_MAX:
|
||||
new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, parent_area.y2) : parent_area.y2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Do nothing if the coordinates are not changed*/
|
||||
if(cont->coords.x1 != new_area.x1 || cont->coords.y1 != new_area.y1 || cont->coords.x2 != new_area.x2 ||
|
||||
cont->coords.y2 != new_area.y2) {
|
||||
|
||||
lv_obj_invalidate(cont);
|
||||
lv_area_copy(&cont->coords, &new_area);
|
||||
lv_obj_invalidate(cont);
|
||||
|
||||
/*Notify the object about its new coordinates*/
|
||||
cont->signal_cb(cont, LV_SIGNAL_COORD_CHG, &ori);
|
||||
|
||||
/*Inform the parent about the new coordinates*/
|
||||
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, cont);
|
||||
|
||||
if(lv_obj_get_auto_realign(cont)) {
|
||||
lv_obj_realign(cont);
|
||||
}
|
||||
|
||||
/*Tell the children the parent's size has changed*/
|
||||
_LV_LL_READ(cont->child_ll, child_i) {
|
||||
child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, &ori);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,223 +0,0 @@
|
||||
/**
|
||||
* @file lv_cont.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_CONT_H
|
||||
#define LV_CONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_CONT != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Container layout options*/
|
||||
enum {
|
||||
LV_LAYOUT_OFF = 0, /**< No layout */
|
||||
LV_LAYOUT_CENTER, /**< Center objects */
|
||||
|
||||
/**
|
||||
* COULMN:
|
||||
* - Place the object below each other
|
||||
* - Keep `pad_top` space on the top
|
||||
* - Keep `pad_inner` space between the objects
|
||||
*/
|
||||
LV_LAYOUT_COLUMN_LEFT, /**< Column left align*/
|
||||
LV_LAYOUT_COLUMN_MID, /**< Column middle align*/
|
||||
LV_LAYOUT_COLUMN_RIGHT, /**< Column right align*/
|
||||
|
||||
/**
|
||||
* ROW:
|
||||
* - Place the object next to each other
|
||||
* - Keep `pad_left` space on the left
|
||||
* - Keep `pad_inner` space between the objects
|
||||
* - If the object which applies the layout has `base_dir == LV_BIDI_DIR_RTL`
|
||||
* the row will start from the right applying `pad.right` space
|
||||
*/
|
||||
LV_LAYOUT_ROW_TOP, /**< Row top align*/
|
||||
LV_LAYOUT_ROW_MID, /**< Row middle align*/
|
||||
LV_LAYOUT_ROW_BOTTOM, /**< Row bottom align*/
|
||||
|
||||
|
||||
/**
|
||||
* PRETTY:
|
||||
* - Place the object next to each other
|
||||
* - If there is no more space start a new row
|
||||
* - Respect `pad_left` and `pad_right` when determining the available space in a row
|
||||
* - Keep `pad_inner` space between the objects in the same row
|
||||
* - Keep `pad_inner` space between the objects in rows
|
||||
* - Divide the remaining horizontal space equally
|
||||
*/
|
||||
LV_LAYOUT_PRETTY_TOP, /**< Row top align*/
|
||||
LV_LAYOUT_PRETTY_MID, /**< Row middle align*/
|
||||
LV_LAYOUT_PRETTY_BOTTOM, /**< Row bottom align*/
|
||||
|
||||
/**
|
||||
* GRID
|
||||
* - Place the object next to each other
|
||||
* - If there is no more space start a new row
|
||||
* - Respect `pad_left` and `pad_right` when determining the available space in a row
|
||||
* - Keep `pad_inner` space between the objects in the same row
|
||||
* - Keep `pad_inner` space between the objects in rows
|
||||
* - Unlike `PRETTY`, `GRID` always keep `pad_inner` space horizontally between objects
|
||||
* so it doesn't divide the remaining horizontal space equally
|
||||
*/
|
||||
LV_LAYOUT_GRID, /**< Align same-sized object into a grid*/
|
||||
|
||||
_LV_LAYOUT_LAST
|
||||
};
|
||||
typedef uint8_t lv_layout_t;
|
||||
|
||||
/**
|
||||
* How to resize the container around the children.
|
||||
*/
|
||||
enum {
|
||||
LV_FIT_NONE, /**< Do not change the size automatically*/
|
||||
LV_FIT_TIGHT, /**< Shrink wrap around the children */
|
||||
LV_FIT_PARENT, /**< Align the size to the parent's edge*/
|
||||
LV_FIT_MAX, /**< Align the size to the parent's edge first but if there is an object out of it
|
||||
then get larger */
|
||||
_LV_FIT_LAST
|
||||
};
|
||||
typedef uint8_t lv_fit_t;
|
||||
|
||||
typedef struct {
|
||||
/*Inherited from 'base_obj' so no inherited ext. */ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_layout_t layout : 4; /*A layout from 'lv_layout_t' enum*/
|
||||
lv_fit_t fit_left : 2; /*A fit type from `lv_fit_t` enum */
|
||||
lv_fit_t fit_right : 2; /*A fit type from `lv_fit_t` enum */
|
||||
lv_fit_t fit_top : 2; /*A fit type from `lv_fit_t` enum */
|
||||
lv_fit_t fit_bottom : 2; /*A fit type from `lv_fit_t` enum */
|
||||
} lv_cont_ext_t;
|
||||
|
||||
/*Part of the container*/
|
||||
enum {
|
||||
LV_CONT_PART_MAIN = LV_OBJ_PART_MAIN,
|
||||
_LV_CONT_PART_VIRTUAL_LAST = _LV_OBJ_PART_VIRTUAL_LAST,
|
||||
_LV_CONT_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a container objects
|
||||
* @param par pointer to an object, it will be the parent of the new container
|
||||
* @param copy pointer to a container object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created container
|
||||
*/
|
||||
lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set a layout on a container
|
||||
* @param cont pointer to a container object
|
||||
* @param layout a layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout);
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 directions separately.
|
||||
* It tell how to change the container's size automatically.
|
||||
* @param cont pointer to a container object
|
||||
* @param left left fit policy from `lv_fit_t`
|
||||
* @param right right fit policy from `lv_fit_t`
|
||||
* @param top top fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom);
|
||||
|
||||
/**
|
||||
* Set the fit policy horizontally and vertically separately.
|
||||
* It tells how to change the container's size automatically.
|
||||
* @param cont pointer to a container object
|
||||
* @param hor horizontal fit policy from `lv_fit_t`
|
||||
* @param ver vertical fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_cont_set_fit2(lv_obj_t * cont, lv_fit_t hor, lv_fit_t ver)
|
||||
{
|
||||
lv_cont_set_fit4(cont, hor, hor, ver, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 direction at once.
|
||||
* It tells how to change the container's size automatically.
|
||||
* @param cont pointer to a container object
|
||||
* @param fit fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)
|
||||
{
|
||||
lv_cont_set_fit4(cont, fit, fit, fit, fit);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the layout of a container
|
||||
* @param cont pointer to container object
|
||||
* @return the layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
lv_layout_t lv_cont_get_layout(const lv_obj_t * cont);
|
||||
|
||||
/**
|
||||
* Get left fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont);
|
||||
|
||||
/**
|
||||
* Get right fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont);
|
||||
|
||||
/**
|
||||
* Get top fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont);
|
||||
|
||||
/**
|
||||
* Get bottom fit mode of a container
|
||||
* @param cont pointer to a container object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CONT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CONT_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,229 +0,0 @@
|
||||
/**
|
||||
* @file lv_cpicker.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_CPICKER_H
|
||||
#define LV_CPICKER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_CPICKER != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
enum {
|
||||
LV_CPICKER_TYPE_RECT,
|
||||
LV_CPICKER_TYPE_DISC,
|
||||
};
|
||||
typedef uint8_t lv_cpicker_type_t;
|
||||
|
||||
enum {
|
||||
LV_CPICKER_COLOR_MODE_HUE,
|
||||
LV_CPICKER_COLOR_MODE_SATURATION,
|
||||
LV_CPICKER_COLOR_MODE_VALUE
|
||||
};
|
||||
typedef uint8_t lv_cpicker_color_mode_t;
|
||||
|
||||
|
||||
|
||||
/*Data of colorpicker*/
|
||||
typedef struct {
|
||||
lv_color_hsv_t hsv;
|
||||
struct {
|
||||
lv_style_list_t style_list;
|
||||
lv_point_t pos;
|
||||
uint8_t colored : 1;
|
||||
|
||||
} knob;
|
||||
uint32_t last_click_time;
|
||||
uint32_t last_change_time;
|
||||
lv_point_t last_press_point;
|
||||
lv_cpicker_color_mode_t color_mode : 2;
|
||||
uint8_t color_mode_fixed : 1;
|
||||
lv_cpicker_type_t type : 1;
|
||||
} lv_cpicker_ext_t;
|
||||
|
||||
/*Parts*/
|
||||
enum {
|
||||
LV_CPICKER_PART_MAIN = LV_OBJ_PART_MAIN,
|
||||
LV_CPICKER_PART_KNOB = _LV_OBJ_PART_VIRTUAL_LAST,
|
||||
_LV_CPICKER_PART_VIRTUAL_LAST,
|
||||
_LV_CPICKER_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a colorpicker objects
|
||||
* @param par pointer to an object, it will be the parent of the new colorpicker
|
||||
* @param copy pointer to a colorpicker object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created colorpicker
|
||||
*/
|
||||
lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set a new type for a colorpicker
|
||||
* @param cpicker pointer to a colorpicker object
|
||||
* @param type new type of the colorpicker (from 'lv_cpicker_type_t' enum)
|
||||
*/
|
||||
void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type);
|
||||
|
||||
/**
|
||||
* Set the current hue of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param hue current selected hue [0..360]
|
||||
* @return true if changed, otherwise false
|
||||
*/
|
||||
bool lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue);
|
||||
|
||||
/**
|
||||
* Set the current saturation of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param saturation current selected saturation [0..100]
|
||||
* @return true if changed, otherwise false
|
||||
*/
|
||||
bool lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation);
|
||||
|
||||
/**
|
||||
* Set the current value of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param val current selected value [0..100]
|
||||
* @return true if changed, otherwise false
|
||||
*/
|
||||
bool lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val);
|
||||
|
||||
/**
|
||||
* Set the current hsv of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param hsv current selected hsv
|
||||
* @return true if changed, otherwise false
|
||||
*/
|
||||
bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv);
|
||||
|
||||
/**
|
||||
* Set the current color of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param color current selected color
|
||||
* @return true if changed, otherwise false
|
||||
*/
|
||||
bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set the current color mode.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param mode color mode (hue/sat/val)
|
||||
*/
|
||||
void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode);
|
||||
|
||||
/**
|
||||
* Set if the color mode is changed on long press on center
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param fixed color mode cannot be changed on long press
|
||||
*/
|
||||
void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed);
|
||||
|
||||
/**
|
||||
* Make the knob to be colored to the current color
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @param en true: color the knob; false: not color the knob
|
||||
*/
|
||||
void lv_cpicker_set_knob_colored(lv_obj_t * cpicker, bool en);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the current color mode.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return color mode (hue/sat/val)
|
||||
*/
|
||||
lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get if the color mode is changed on long press on center
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return mode cannot be changed on long press
|
||||
*/
|
||||
bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get the current hue of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return current selected hue
|
||||
*/
|
||||
uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get the current saturation of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return current selected saturation
|
||||
*/
|
||||
uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get the current hue of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return current selected value
|
||||
*/
|
||||
uint8_t lv_cpicker_get_value(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get the current selected hsv of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return current selected hsv
|
||||
*/
|
||||
lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Get the current selected color of a colorpicker.
|
||||
* @param cpicker pointer to colorpicker object
|
||||
* @return current selected color
|
||||
*/
|
||||
lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker);
|
||||
|
||||
/**
|
||||
* Whether the knob is colored to the current color or not
|
||||
* @param cpicker pointer to color picker object
|
||||
* @return true: color the knob; false: not color the knob
|
||||
*/
|
||||
bool lv_cpicker_get_knob_colored(lv_obj_t * cpicker);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_CPICKER*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_CPICKER_H*/
|
||||
@@ -36,22 +36,21 @@
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_page_ext_t page;
|
||||
/*No inherited ext*/
|
||||
lv_obj_t * ddlist; /*Pointer to the ddlist where the page belongs*/
|
||||
} lv_dropdown_page_ext_t;
|
||||
} lv_dropdown_list_ext_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_design_res_t lv_dropdown_page_design(lv_obj_t * ddlist, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_design_res_t lv_dropdown_list_design(lv_obj_t * ddlist, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_dropdown_page_signal(lv_obj_t * page, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_dropdown_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_dropdown_page_signal(lv_obj_t * list, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_dropdown_get_style(lv_obj_t * ddlist, uint8_t part);
|
||||
static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id, lv_state_t state);
|
||||
static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id, lv_state_t state);
|
||||
static lv_res_t page_release_handler(lv_obj_t * page);
|
||||
static lv_res_t list_release_handler(lv_obj_t * page);
|
||||
static void page_press_handler(lv_obj_t * page);
|
||||
static uint16_t get_id_on_point(lv_obj_t * ddlist, lv_coord_t y);
|
||||
static void position_to_selected(lv_obj_t * ddlist);
|
||||
@@ -61,10 +60,9 @@ static lv_obj_t * get_label(const lv_obj_t * ddlist);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_signal_cb_t ancestor_page_signal;
|
||||
static lv_signal_cb_t ancestor_page_scrl_signal;
|
||||
static lv_signal_cb_t ancestor_list_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_design_cb_t ancestor_page_design;
|
||||
static lv_design_cb_t ancestor_list_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -102,20 +100,18 @@ lv_obj_t * lv_dropdown_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
}
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->page = NULL;
|
||||
ext->list = NULL;
|
||||
ext->options = NULL;
|
||||
ext->symbol = LV_SYMBOL_DOWN;
|
||||
ext->text = "Select";
|
||||
ext->text = NULL;
|
||||
ext->static_txt = 1;
|
||||
ext->show_selected = 1;
|
||||
ext->sel_opt_id = 0;
|
||||
ext->sel_opt_id_orig = 0;
|
||||
ext->pr_opt_id = LV_DROPDOWN_PR_NONE;
|
||||
ext->option_cnt = 0;
|
||||
ext->dir = LV_DROPDOWN_DIR_DOWN;
|
||||
ext->dir = LV_DIR_BOTTOM;
|
||||
ext->max_height = (3 * lv_disp_get_ver_res(NULL)) / 4;
|
||||
lv_style_list_init(&ext->style_page);
|
||||
lv_style_list_init(&ext->style_scrlbar);
|
||||
lv_style_list_init(&ext->style_list);
|
||||
lv_style_list_init(&ext->style_selected);
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
@@ -142,10 +138,8 @@ lv_obj_t * lv_dropdown_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->max_height = copy_ext->max_height;
|
||||
ext->text = copy_ext->text;
|
||||
ext->dir = copy_ext->dir;
|
||||
ext->show_selected = copy_ext->show_selected;
|
||||
lv_style_list_copy(&ext->style_page, ©_ext->style_page);
|
||||
lv_style_list_copy(&ext->style_list, ©_ext->style_list);
|
||||
lv_style_list_copy(&ext->style_selected, ©_ext->style_selected);
|
||||
lv_style_list_copy(&ext->style_scrlbar, ©_ext->style_scrlbar);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("drop down list created");
|
||||
@@ -174,7 +168,7 @@ void lv_dropdown_set_text(lv_obj_t * ddlist, const char * txt)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any options in a drop down list. Static or dynamic.
|
||||
* Clear all options in a drop down list. Static or dynamic.
|
||||
* @param ddlist pointer to drop down list object
|
||||
*/
|
||||
void lv_dropdown_clear_options(lv_obj_t * ddlist)
|
||||
@@ -347,7 +341,7 @@ void lv_dropdown_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)
|
||||
ext->sel_opt_id = sel_opt < ext->option_cnt ? sel_opt : ext->option_cnt - 1;
|
||||
ext->sel_opt_id_orig = ext->sel_opt_id;
|
||||
/*Move the list to show the current option*/
|
||||
if(ext->page != NULL) {
|
||||
if(ext->list != NULL) {
|
||||
lv_obj_invalidate(ddlist);
|
||||
}
|
||||
}
|
||||
@@ -355,9 +349,9 @@ void lv_dropdown_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)
|
||||
/**
|
||||
* Set the direction of the a drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param dir LV_DROPDOWN_DIR_LEF/RIGHT/TOP/BOTTOM
|
||||
* @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM
|
||||
*/
|
||||
void lv_dropdown_set_dir(lv_obj_t * ddlist, lv_dropdown_dir_t dir)
|
||||
void lv_dropdown_set_dir(lv_obj_t * ddlist, lv_dir_t dir)
|
||||
{
|
||||
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
|
||||
|
||||
@@ -382,16 +376,6 @@ void lv_dropdown_set_max_height(lv_obj_t * ddlist, lv_coord_t h)
|
||||
if(ext->max_height == h) return;
|
||||
|
||||
ext->max_height = h;
|
||||
|
||||
if(ext->page) {
|
||||
if(h == 0) {
|
||||
lv_cont_set_fit(ext->page, LV_FIT_TIGHT);
|
||||
}
|
||||
else {
|
||||
lv_cont_set_fit2(ext->page, LV_FIT_TIGHT, LV_FIT_NONE);
|
||||
lv_obj_set_height(ext->page, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,23 +392,6 @@ void lv_dropdown_set_symbol(lv_obj_t * ddlist, const char * symbol)
|
||||
lv_obj_invalidate(ddlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the ddlist highlight the last selected option and display its text or not
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param show true/false
|
||||
*/
|
||||
void lv_dropdown_set_show_selected(lv_obj_t * ddlist, bool show)
|
||||
{
|
||||
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
|
||||
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
if(ext->show_selected == show) return;
|
||||
|
||||
ext->show_selected = show;
|
||||
|
||||
lv_obj_invalidate(ddlist);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -545,9 +512,9 @@ const char * lv_dropdown_get_symbol(lv_obj_t * ddlist)
|
||||
/**
|
||||
* Get the direction of the drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @return LV_DROPDOWN_DIR_LEF/RIGHT/TOP/BOTTOM
|
||||
* @return LV_DIR_LEF/RIGHT/TOP/BOTTOM
|
||||
*/
|
||||
lv_dropdown_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist)
|
||||
lv_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist)
|
||||
{
|
||||
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
|
||||
|
||||
@@ -556,21 +523,6 @@ lv_dropdown_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist)
|
||||
return ext->dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the ddlist highlight the last selected option and display its text or not
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_dropdown_get_show_selected(lv_obj_t * ddlist)
|
||||
{
|
||||
LV_ASSERT_OBJ(ddlist, LV_OBJX_NAME);
|
||||
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
return ext->show_selected ? true : false;
|
||||
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
@@ -582,46 +534,37 @@ bool lv_dropdown_get_show_selected(lv_obj_t * ddlist)
|
||||
void lv_dropdown_open(lv_obj_t * ddlist)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
if(ext->page) return;
|
||||
if(ext->list) return;
|
||||
|
||||
ext->page = lv_page_create(lv_obj_get_screen(ddlist), NULL);
|
||||
lv_obj_add_protect(ext->page, LV_PROTECT_POS | LV_PROTECT_CLICK_FOCUS);
|
||||
lv_obj_add_protect(lv_page_get_scrollable(ext->page), LV_PROTECT_CLICK_FOCUS);
|
||||
ext->list = lv_obj_create(lv_obj_get_screen(ddlist), NULL);
|
||||
lv_obj_clear_flag(ext->list, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
|
||||
lv_obj_set_base_dir(ext->page, lv_obj_get_base_dir(ddlist));
|
||||
if(ancestor_list_signal == NULL) ancestor_list_signal = lv_obj_get_signal_cb(ext->list);
|
||||
if(ancestor_list_design == NULL) ancestor_list_design = lv_obj_get_design_cb(ext->list);
|
||||
|
||||
if(ancestor_page_signal == NULL) ancestor_page_signal = lv_obj_get_signal_cb(ext->page);
|
||||
if(ancestor_page_scrl_signal == NULL) ancestor_page_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrollable(
|
||||
ext->page));
|
||||
if(ancestor_page_design == NULL) ancestor_page_design = lv_obj_get_design_cb(ext->page);
|
||||
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_allocate_ext_attr(ext->page, sizeof(lv_dropdown_page_ext_t));
|
||||
LV_ASSERT_MEM(page_ext);
|
||||
if(page_ext == NULL) {
|
||||
lv_obj_del(ext->page);
|
||||
ext->page = NULL;
|
||||
lv_dropdown_list_ext_t * list_ext = lv_obj_allocate_ext_attr(ext->list, sizeof(lv_dropdown_list_ext_t));
|
||||
LV_ASSERT_MEM(list_ext);
|
||||
if(list_ext == NULL) {
|
||||
lv_obj_del(ext->list);
|
||||
ext->list = NULL;
|
||||
return;
|
||||
}
|
||||
page_ext->ddlist = ddlist;
|
||||
list_ext->ddlist = ddlist;
|
||||
|
||||
lv_obj_set_design_cb(ext->page, lv_dropdown_page_design);
|
||||
lv_obj_set_signal_cb(ext->page, lv_dropdown_page_signal);
|
||||
lv_obj_set_signal_cb(lv_page_get_scrollable(ext->page), lv_dropdown_page_scrl_signal);
|
||||
lv_obj_set_design_cb(ext->list, lv_dropdown_list_design);
|
||||
lv_obj_set_signal_cb(ext->list, lv_dropdown_page_signal);
|
||||
|
||||
lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_BG), &ext->style_page);
|
||||
lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_SCROLLBAR), &ext->style_scrlbar);
|
||||
lv_obj_clean_style_list(ext->page, LV_PAGE_PART_SCROLLABLE);
|
||||
lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
lv_style_list_copy(_lv_obj_get_style_list(ext->list, LV_OBJ_PART_MAIN), &ext->style_list);
|
||||
_lv_obj_refresh_style(ext->list, LV_OBJ_PART_MAIN, LV_STYLE_PROP_ALL);
|
||||
|
||||
lv_obj_t * label = lv_label_create(ext->page, NULL);
|
||||
lv_obj_t * label = lv_label_create(ext->list, NULL);
|
||||
lv_label_set_text_static(label, ext->options);
|
||||
lv_obj_set_width(ext->list, LV_SIZE_AUTO);
|
||||
|
||||
lv_cont_set_fit2(ext->page, LV_FIT_TIGHT, LV_FIT_NONE);
|
||||
/*Set small width to the width of the button*/
|
||||
if(lv_obj_get_width(ext->page) < lv_obj_get_width(ddlist) &&
|
||||
(ext->dir == LV_DROPDOWN_DIR_UP || ext->dir == LV_DROPDOWN_DIR_DOWN)) {
|
||||
lv_cont_set_fit2(ext->page, LV_FIT_NONE, LV_FIT_NONE);
|
||||
lv_obj_set_width(ext->page, lv_obj_get_width(ddlist));
|
||||
/*Set smaller width to the width of the button*/
|
||||
if(lv_obj_get_width(ext->list) < lv_obj_get_width_fit(ddlist) &&
|
||||
(ext->dir == LV_DIR_TOP || ext->dir == LV_DIR_BOTTOM)) {
|
||||
lv_obj_set_width(ext->list, lv_obj_get_width(ddlist));
|
||||
}
|
||||
|
||||
lv_coord_t label_h = lv_obj_get_height(label);
|
||||
@@ -632,13 +575,13 @@ void lv_dropdown_open(lv_obj_t * ddlist)
|
||||
lv_coord_t list_h = list_fit_h;
|
||||
if(list_h > ext->max_height) list_h = ext->max_height;
|
||||
|
||||
lv_dropdown_dir_t dir = ext->dir;
|
||||
/*No place on the bottom? See if top is better.*/
|
||||
if(ext->dir == LV_DROPDOWN_DIR_DOWN) {
|
||||
lv_dir_t dir = ext->dir;
|
||||
/*No space on the bottom? See if top is better.*/
|
||||
if(ext->dir == LV_DIR_BOTTOM) {
|
||||
if(ddlist->coords.y2 + list_h > LV_VER_RES) {
|
||||
if(ddlist->coords.y1 > LV_VER_RES - ddlist->coords.y2) {
|
||||
/*There is more space on the top, so make it drop up*/
|
||||
dir = LV_DROPDOWN_DIR_UP;
|
||||
dir = LV_DIR_TOP;
|
||||
list_h = ddlist->coords.y1;
|
||||
}
|
||||
else {
|
||||
@@ -646,12 +589,12 @@ void lv_dropdown_open(lv_obj_t * ddlist)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*No place on the top? See if bottom is better.*/
|
||||
else if(ext->dir == LV_DROPDOWN_DIR_UP) {
|
||||
/*No space on the top? See if bottom is better.*/
|
||||
else if(ext->dir == LV_DIR_TOP) {
|
||||
if(ddlist->coords.y1 - list_h < 0) {
|
||||
if(ddlist->coords.y1 < LV_VER_RES - ddlist->coords.y2) {
|
||||
/*There is more space on the top, so make it drop up*/
|
||||
dir = LV_DROPDOWN_DIR_DOWN;
|
||||
dir = LV_DIR_BOTTOM;
|
||||
list_h = LV_VER_RES - ddlist->coords.y2;
|
||||
}
|
||||
else {
|
||||
@@ -663,23 +606,23 @@ void lv_dropdown_open(lv_obj_t * ddlist)
|
||||
if(list_h > list_fit_h) list_h = list_fit_h;
|
||||
if(list_h > ext->max_height) list_h = ext->max_height;
|
||||
|
||||
lv_obj_set_height(ext->page, list_h);
|
||||
lv_obj_set_height(ext->list, list_h);
|
||||
|
||||
position_to_selected(ddlist);
|
||||
|
||||
if(dir == LV_DROPDOWN_DIR_DOWN) lv_obj_align(ext->page, ddlist, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
|
||||
else if(dir == LV_DROPDOWN_DIR_UP) lv_obj_align(ext->page, ddlist, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
|
||||
else if(dir == LV_DROPDOWN_DIR_LEFT) lv_obj_align(ext->page, ddlist, LV_ALIGN_OUT_LEFT_TOP, 0, 0);
|
||||
else if(dir == LV_DROPDOWN_DIR_RIGHT)lv_obj_align(ext->page, ddlist, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
|
||||
if(dir == LV_DIR_BOTTOM) lv_obj_align(ext->list, ddlist, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
|
||||
else if(dir == LV_DIR_TOP) lv_obj_align(ext->list, ddlist, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
|
||||
else if(dir == LV_DIR_LEFT) lv_obj_align(ext->list, ddlist, LV_ALIGN_OUT_LEFT_TOP, 0, 0);
|
||||
else if(dir == LV_DIR_RIGHT)lv_obj_align(ext->list, ddlist, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
|
||||
|
||||
if(ext->dir == LV_DROPDOWN_DIR_LEFT || ext->dir == LV_DROPDOWN_DIR_RIGHT) {
|
||||
if(ext->page->coords.y2 > LV_VER_RES) {
|
||||
lv_obj_set_y(ext->page, lv_obj_get_y(ext->page) - (ext->page->coords.y2 - LV_VER_RES));
|
||||
if(ext->dir == LV_DIR_LEFT || ext->dir == LV_DIR_RIGHT) {
|
||||
if(ext->list->coords.y2 > LV_VER_RES) {
|
||||
lv_obj_set_y(ext->list, lv_obj_get_y(ext->list) - (ext->list->coords.y2 - LV_VER_RES));
|
||||
}
|
||||
}
|
||||
|
||||
if(lv_label_get_align(label) == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_obj_set_x(label, lv_obj_get_width_fit(ext->page) - lv_obj_get_width(label));
|
||||
lv_obj_set_x(label, lv_obj_get_width_fit(ext->list) - lv_obj_get_width(label));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,11 +633,11 @@ void lv_dropdown_open(lv_obj_t * ddlist)
|
||||
void lv_dropdown_close(lv_obj_t * ddlist)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
if(ext->page == NULL) return;
|
||||
if(ext->list == NULL) return;
|
||||
|
||||
ext->pr_opt_id = LV_DROPDOWN_PR_NONE;
|
||||
lv_obj_del(ext->page);
|
||||
ext->page = NULL;
|
||||
lv_obj_del(ext->list);
|
||||
ext->list = NULL;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@@ -734,8 +677,10 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
|
||||
lv_area_t txt_area;
|
||||
lv_point_t txt_size;
|
||||
|
||||
const char * opt_txt = ext->text;
|
||||
if(ext->show_selected) {
|
||||
/*If no text specified use the selected option*/
|
||||
const char * opt_txt;
|
||||
if(ext->text) opt_txt = ext->text;
|
||||
else {
|
||||
char * buf = _lv_mem_buf_get(128);
|
||||
lv_dropdown_get_selected_str(ddlist, buf, 128);
|
||||
opt_txt = buf;
|
||||
@@ -744,7 +689,7 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
|
||||
const char * txt;
|
||||
|
||||
bool rev = false;
|
||||
if(ext->dir == LV_DROPDOWN_DIR_LEFT) rev = true;
|
||||
if(ext->dir == LV_DIR_LEFT) rev = true;
|
||||
if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) rev = true;
|
||||
|
||||
txt = rev ? ext->symbol : opt_txt;
|
||||
@@ -787,7 +732,7 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
|
||||
lv_draw_label(&txt_area, clip_area, &label_dsc, txt, NULL);
|
||||
}
|
||||
|
||||
if(ext->show_selected) {
|
||||
if(ext->text == NULL) {
|
||||
_lv_mem_buf_release((char *)opt_txt);
|
||||
}
|
||||
|
||||
@@ -800,8 +745,8 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the drop down list's page
|
||||
* @param page pointer to an object
|
||||
* Handle the drawing related tasks of the drop down list's list
|
||||
* @param list pointer to an object
|
||||
* @param clip_area 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)
|
||||
@@ -809,27 +754,27 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return an element of `lv_design_res_t`
|
||||
*/
|
||||
static lv_design_res_t lv_dropdown_page_design(lv_obj_t * page, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
static lv_design_res_t lv_dropdown_list_design(lv_obj_t * page, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
{
|
||||
/*Return false if the object is not covers the mask_p area*/
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_page_design(page, clip_area, mode);
|
||||
return ancestor_list_design(page, clip_area, mode);
|
||||
}
|
||||
/*Draw the object*/
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
ancestor_page_design(page, clip_area, mode);
|
||||
ancestor_list_design(page, clip_area, mode);
|
||||
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_dropdown_list_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
/*Draw the boxes if the page is not being deleted*/
|
||||
if(ext->page) {
|
||||
if(ext->list) {
|
||||
/* Clip area might be too large too to shadow but
|
||||
* the selected option can be drawn on only the background*/
|
||||
lv_area_t clip_area_core;
|
||||
bool has_common;
|
||||
has_common = _lv_area_intersect(&clip_area_core, clip_area, &ext->page->coords);
|
||||
has_common = _lv_area_intersect(&clip_area_core, clip_area, &ext->list->coords);
|
||||
if(has_common) {
|
||||
if(ext->pr_opt_id != LV_DROPDOWN_PR_NONE) {
|
||||
draw_box(ddlist, &clip_area_core, ext->pr_opt_id, LV_STATE_PRESSED);
|
||||
@@ -841,21 +786,21 @@ static lv_design_res_t lv_dropdown_page_design(lv_obj_t * page, const lv_area_t
|
||||
}
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
/*Draw the scrollbar in the ancestor page design function*/
|
||||
ancestor_page_design(page, clip_area, mode);
|
||||
/*Draw the scrollbar in the ancestor list design function*/
|
||||
ancestor_list_design(page, clip_area, mode);
|
||||
|
||||
/*Redraw the text on the selected area with a different color*/
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_dropdown_list_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
/*Draw the box labels if the page is not being deleted*/
|
||||
if(ext->page) {
|
||||
/*Draw the box labels if the list is not being deleted*/
|
||||
if(ext->list) {
|
||||
/* Clip area might be too large too to shadow but
|
||||
* the selected option can be drawn on only the background*/
|
||||
lv_area_t clip_area_core;
|
||||
bool has_common;
|
||||
has_common = _lv_area_intersect(&clip_area_core, clip_area, &ext->page->coords);
|
||||
has_common = _lv_area_intersect(&clip_area_core, clip_area, &ext->list->coords);
|
||||
if(has_common) {
|
||||
if(ext->pr_opt_id != LV_DROPDOWN_PR_NONE) {
|
||||
draw_box_label(ddlist, &clip_area_core, ext->pr_opt_id, LV_STATE_PRESSED);
|
||||
@@ -883,7 +828,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(ddlist, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
@@ -893,14 +838,6 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_STATE_DSC) {
|
||||
lv_get_state_info_t * info = param;
|
||||
if(info->part == LV_DROPDOWN_PART_LIST ||
|
||||
info->part == LV_DROPDOWN_PART_SCROLLBAR ||
|
||||
info->part == LV_DROPDOWN_PART_SELECTED) {
|
||||
info->result = lv_obj_get_state(ext->page, LV_PAGE_PART_BG);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_dropdown_close(ddlist);
|
||||
if(ext->static_txt == 0) {
|
||||
@@ -908,10 +845,9 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
ext->options = NULL;
|
||||
}
|
||||
|
||||
/*`lv_obj_clean_style_list` is not required because these styles are only copied to the page
|
||||
/*`lv_obj_clean_style_list` is not required because these styles are only copied to the list
|
||||
* so they can have transitions or other object related things. */
|
||||
_lv_style_list_reset(&ext->style_page);
|
||||
_lv_style_list_reset(&ext->style_scrlbar);
|
||||
_lv_style_list_reset(&ext->style_list);
|
||||
_lv_style_list_reset(&ext->style_selected);
|
||||
|
||||
}
|
||||
@@ -936,8 +872,8 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
if(lv_indev_is_dragging(indev) == false) {
|
||||
if(ext->page) {
|
||||
if(lv_indev_get_scroll_obj(indev) == NULL) {
|
||||
if(ext->list) {
|
||||
lv_dropdown_close(ddlist);
|
||||
if(ext->sel_opt_id_orig != ext->sel_opt_id) {
|
||||
ext->sel_opt_id_orig = ext->sel_opt_id;
|
||||
@@ -963,7 +899,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
if(ext->page) lv_dropdown_close(ddlist);
|
||||
if(ext->list) lv_dropdown_close(ddlist);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(ddlist, LV_DROPDOWN_PART_MAIN);
|
||||
@@ -971,13 +907,13 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_MAIN);
|
||||
lv_obj_set_height(ddlist, top + bottom + lv_font_get_line_height(font));
|
||||
|
||||
if(ext->page) lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
if(ext->list) _lv_obj_refresh_style(ext->list, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
#if LV_USE_GROUP
|
||||
char c = *((char *)param);
|
||||
if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {
|
||||
if(ext->page == NULL) {
|
||||
if(ext->list == NULL) {
|
||||
lv_dropdown_open(ddlist);
|
||||
}
|
||||
else if(ext->sel_opt_id + 1 < ext->option_cnt) {
|
||||
@@ -987,7 +923,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
}
|
||||
else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {
|
||||
|
||||
if(ext->page == NULL) {
|
||||
if(ext->list == NULL) {
|
||||
lv_dropdown_open(ddlist);
|
||||
}
|
||||
else if(ext->sel_opt_id > 0) {
|
||||
@@ -1018,92 +954,40 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_dropdown_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
static lv_res_t lv_dropdown_page_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_page_signal(page, sign, param);
|
||||
res = ancestor_list_signal(list, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
|
||||
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
lv_dropdown_list_ext_t * list_ext = lv_obj_get_ext_attr(list);
|
||||
lv_obj_t * ddlist = list_ext->ddlist;
|
||||
|
||||
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
/* Make possible to draw on the full width of the background to redraw the selected rectangle
|
||||
* when the ddlist is scrolled in fix height mode.
|
||||
* (The scrollable is scrolled then "select rectangle" is drawn on the bg too)*/
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(page);
|
||||
scrl->ext_draw_pad = LV_MATH_MAX3(scrl->ext_draw_pad, left, right);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false) {
|
||||
page_release_handler(page);
|
||||
if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_indev_get_scroll_obj(lv_indev_get_act()) == NULL) {
|
||||
list_release_handler(list);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED) {
|
||||
page_press_handler(page);
|
||||
page_press_handler(list);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
ext->page = NULL; /*The page is just being deleted*/
|
||||
ext->list = NULL; /*The list is just being deleted*/
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the drop down list's scrollable part
|
||||
* @param scrl pointer to a drop down list's scrollable part
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_dropdown_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_page_scrl_signal(scrl, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
|
||||
|
||||
lv_obj_t * page = lv_obj_get_parent(scrl);
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false) {
|
||||
page_release_handler(page);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED) {
|
||||
page_press_handler(page);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_DRAG_BEGIN) {
|
||||
else if(sign == LV_SIGNAL_SCROLL_BEGIN) {
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
ext->pr_opt_id = LV_DROPDOWN_PR_NONE;
|
||||
lv_obj_invalidate(page);
|
||||
lv_obj_invalidate(list);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
/* Make possible to draw on the full width of the background to redraw the selected rectangle
|
||||
* when the ddlist is scrolled in fix height mode.
|
||||
* (The scrollable is scrolled then "select rectangle" is drawn on the bg too)*/
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
scrl->ext_draw_pad = LV_MATH_MAX3(scrl->ext_draw_pad, left, right);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the style descriptor of a part of the object
|
||||
* @param page pointer the object
|
||||
* @param list pointer the object
|
||||
* @param part the part from `lv_dropdown_part_t`. (LV_DROPDOWN_PART_...)
|
||||
* @return pointer to the style descriptor of the specified part
|
||||
*/
|
||||
@@ -1119,10 +1003,7 @@ static lv_style_list_t * lv_dropdown_get_style(lv_obj_t * ddlist, uint8_t part)
|
||||
style_dsc_p = &ddlist->style_list;
|
||||
break;
|
||||
case LV_DROPDOWN_PART_LIST:
|
||||
style_dsc_p = &ext->style_page;
|
||||
break;
|
||||
case LV_DROPDOWN_PART_SCROLLBAR:
|
||||
style_dsc_p = &ext->style_scrlbar;
|
||||
style_dsc_p = &ext->style_list;
|
||||
break;
|
||||
case LV_DROPDOWN_PART_SELECTED:
|
||||
style_dsc_p = &ext->style_selected;
|
||||
@@ -1137,12 +1018,12 @@ static lv_style_list_t * lv_dropdown_get_style(lv_obj_t * ddlist, uint8_t part)
|
||||
static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id, lv_state_t state)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_obj_t * page = ext->page;
|
||||
lv_state_t state_orig = page->state;
|
||||
lv_obj_t * list = ext->list;
|
||||
lv_state_t state_orig = list->state;
|
||||
|
||||
if(state != page->state) {
|
||||
if(state != list->state) {
|
||||
_lv_obj_disable_style_caching(ddlist, true);
|
||||
page->state = state;
|
||||
list->state = state;
|
||||
}
|
||||
|
||||
/*Draw a rectangle under the selected item*/
|
||||
@@ -1158,15 +1039,15 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id
|
||||
rect_area.y1 -= line_space / 2;
|
||||
|
||||
rect_area.y2 = rect_area.y1 + font_h + line_space - 1;
|
||||
rect_area.x1 = ext->page->coords.x1;
|
||||
rect_area.x2 = ext->page->coords.x2;
|
||||
rect_area.x1 = ext->list->coords.x1;
|
||||
rect_area.x2 = ext->list->coords.x2;
|
||||
|
||||
lv_draw_rect_dsc_t sel_rect;
|
||||
lv_draw_rect_dsc_init(&sel_rect);
|
||||
lv_obj_init_draw_rect_dsc(ddlist, LV_DROPDOWN_PART_SELECTED, &sel_rect);
|
||||
lv_draw_rect(&rect_area, clip_area, &sel_rect);
|
||||
|
||||
page->state = state_orig;
|
||||
list->state = state_orig;
|
||||
_lv_obj_disable_style_caching(ddlist, false);
|
||||
}
|
||||
|
||||
@@ -1175,7 +1056,7 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id
|
||||
static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id, lv_state_t state)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
lv_obj_t * page = ext->page;
|
||||
lv_obj_t * page = ext->list;
|
||||
lv_state_t state_orig = page->state;
|
||||
|
||||
if(state != page->state) {
|
||||
@@ -1188,7 +1069,7 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1
|
||||
lv_obj_init_draw_label_dsc(ddlist, LV_DROPDOWN_PART_SELECTED, &label_dsc);
|
||||
|
||||
label_dsc.line_space = lv_obj_get_style_text_line_space(ddlist,
|
||||
LV_DROPDOWN_PART_LIST); /*Line space should come from the page*/
|
||||
LV_DROPDOWN_PART_LIST); /*Line space should come from the list*/
|
||||
|
||||
lv_obj_t * label = get_label(ddlist);
|
||||
if(label == NULL) return;
|
||||
@@ -1220,12 +1101,12 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1
|
||||
|
||||
/**
|
||||
* Called when a drop down list is released to open it or set new option
|
||||
* @param page pointer to the drop down list's page
|
||||
* @return LV_RES_INV if the page is not being deleted in the user callback. Else LV_RES_OK
|
||||
* @param list pointer to the drop down list's list
|
||||
* @return LV_RES_INV if the list is not being deleted in the user callback. Else LV_RES_OK
|
||||
*/
|
||||
static lv_res_t page_release_handler(lv_obj_t * page)
|
||||
static lv_res_t list_release_handler(lv_obj_t * page)
|
||||
{
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_dropdown_list_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
@@ -1253,19 +1134,19 @@ static lv_res_t page_release_handler(lv_obj_t * page)
|
||||
lv_dropdown_close(ddlist);
|
||||
|
||||
/*Invalidate to refresh the text*/
|
||||
if(ext->show_selected) lv_obj_invalidate(ddlist);
|
||||
if(ext->text == NULL) lv_obj_invalidate(ddlist);
|
||||
|
||||
uint32_t id = ext->sel_opt_id; /*Just to use uint32_t in event data*/
|
||||
lv_res_t res = lv_event_send(ddlist, LV_EVENT_VALUE_CHANGED, &id);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(ext->page == NULL) return LV_RES_INV;
|
||||
if(ext->list == NULL) return LV_RES_INV;
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static void page_press_handler(lv_obj_t * page)
|
||||
{
|
||||
lv_dropdown_page_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_dropdown_list_ext_t * page_ext = lv_obj_get_ext_attr(page);
|
||||
lv_obj_t * ddlist = page_ext->ddlist;
|
||||
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
@@ -1305,29 +1186,32 @@ static void position_to_selected(lv_obj_t * ddlist)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(ext->page);
|
||||
lv_obj_t * label = get_label(ddlist);
|
||||
if(label == NULL) return;
|
||||
|
||||
lv_coord_t h = lv_obj_get_height(ext->page);
|
||||
if(lv_obj_get_height(label) <= lv_obj_get_height_fit(ddlist)) return;
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ddlist, LV_DROPDOWN_PART_LIST);
|
||||
|
||||
lv_coord_t line_y1 = ext->sel_opt_id * (font_h + line_space) + label->coords.y1 - scrl->coords.y1;
|
||||
lv_coord_t line_y1 = ext->sel_opt_id * (font_h + line_space);
|
||||
|
||||
lv_obj_set_y(scrl, -line_y1 + (h - font_h) / 2);
|
||||
lv_obj_invalidate(ext->page);
|
||||
/*Do not allow scrolling in*/
|
||||
lv_coord_t bottom_diff = ext->list->coords.y2 - lv_obj_get_style_pad_bottom(ext->list, LV_OBJ_PART_MAIN) - (label->coords.y2 - line_y1);
|
||||
if(bottom_diff > 0) line_y1 -= bottom_diff;
|
||||
|
||||
/*Scroll to the selected option*/
|
||||
lv_obj_scroll_to_y(ext->list, line_y1, LV_ANIM_OFF);
|
||||
lv_obj_invalidate(ext->list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static lv_obj_t * get_label(const lv_obj_t * ddlist)
|
||||
{
|
||||
lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist);
|
||||
if(ext->page == NULL) return NULL;
|
||||
if(ext->list == NULL) return NULL;
|
||||
|
||||
return lv_obj_get_child(lv_page_get_scrollable(ext->page), NULL);
|
||||
return lv_obj_get_child(ext->list, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,15 +18,11 @@ extern "C" {
|
||||
#if LV_USE_DROPDOWN != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_PAGE == 0
|
||||
#error "lv_ddlist: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL == 0
|
||||
#error "lv_ddlist: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_widgets/lv_page.h"
|
||||
#include "../lv_widgets/lv_label.h"
|
||||
|
||||
/*********************
|
||||
@@ -38,40 +34,29 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
enum {
|
||||
LV_DROPDOWN_DIR_DOWN,
|
||||
LV_DROPDOWN_DIR_UP,
|
||||
LV_DROPDOWN_DIR_LEFT,
|
||||
LV_DROPDOWN_DIR_RIGHT,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_dropdown_dir_t;
|
||||
|
||||
/*Data of drop down list*/
|
||||
typedef struct {
|
||||
/*New data for this type */
|
||||
lv_obj_t * page; /*The dropped down list*/
|
||||
lv_obj_t * list; /*The dropped down list*/
|
||||
const char * text; /*Text to display on the ddlist's button*/
|
||||
const char * symbol; /*Arrow or other icon when the drop-down list is closed*/
|
||||
char * options;
|
||||
lv_style_list_t style_selected; /*Style of the selected option*/
|
||||
lv_style_list_t style_page; /*Style of the dropped down list*/
|
||||
lv_style_list_t style_scrlbar; /*Style of the scroll bar*/
|
||||
lv_style_list_t style_list; /*Style of the dropped down list*/
|
||||
lv_coord_t max_height; /*Height of the ddlist when opened. (0: auto-size)*/
|
||||
uint16_t option_cnt; /*Number of options*/
|
||||
uint16_t sel_opt_id; /*Index of the currently selected option*/
|
||||
uint16_t sel_opt_id_orig; /*Store the original index on focus*/
|
||||
uint16_t pr_opt_id; /*Index of the currently pressed option*/
|
||||
lv_dropdown_dir_t dir : 2;
|
||||
uint8_t show_selected : 1;
|
||||
lv_dir_t dir : 4;
|
||||
uint8_t static_txt : 1;
|
||||
} lv_dropdown_ext_t;
|
||||
|
||||
enum {
|
||||
LV_DROPDOWN_PART_MAIN = LV_OBJ_PART_MAIN,
|
||||
LV_DROPDOWN_PART_LIST = _LV_OBJ_PART_REAL_LAST,
|
||||
LV_DROPDOWN_PART_SCROLLBAR,
|
||||
LV_DROPDOWN_PART_LIST,
|
||||
LV_DROPDOWN_PART_SELECTED,
|
||||
_LV_DROPDOWN_PART_LAST
|
||||
};
|
||||
typedef uint8_t lv_dropdown_part_t;
|
||||
|
||||
@@ -99,7 +84,7 @@ lv_obj_t * lv_dropdown_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
void lv_dropdown_set_text(lv_obj_t * ddlist, const char * txt);
|
||||
|
||||
/**
|
||||
* Clear any options in a drop down list. Static or dynamic.
|
||||
* Clear all options in a drop down list. Static or dynamic.
|
||||
* @param ddlist pointer to drop down list object
|
||||
*/
|
||||
void lv_dropdown_clear_options(lv_obj_t * ddlist);
|
||||
@@ -138,9 +123,9 @@ void lv_dropdown_set_selected(lv_obj_t * ddlist, uint16_t sel_opt);
|
||||
/**
|
||||
* Set the direction of the a drop down list
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param dir LV_DROPDOWN_DIR_LEF/RIGHT/TOP/BOTTOM
|
||||
* @param dir LV_DIR_LEFT/RIGHT/TOP/BOTTOM
|
||||
*/
|
||||
void lv_dropdown_set_dir(lv_obj_t * ddlist, lv_dropdown_dir_t dir);
|
||||
void lv_dropdown_set_dir(lv_obj_t * ddlist, lv_dir_t dir);
|
||||
|
||||
/**
|
||||
* Set the maximal height for the drop down list
|
||||
@@ -156,13 +141,6 @@ void lv_dropdown_set_max_height(lv_obj_t * ddlist, lv_coord_t h);
|
||||
*/
|
||||
void lv_dropdown_set_symbol(lv_obj_t * ddlist, const char * symbol);
|
||||
|
||||
/**
|
||||
* Set whether the ddlist highlight the last selected option and display its text or not
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param show true/false
|
||||
*/
|
||||
void lv_dropdown_set_show_selected(lv_obj_t * ddlist, bool show);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -222,14 +200,7 @@ const char * lv_dropdown_get_symbol(lv_obj_t * ddlist);
|
||||
* @param ddlist pointer to drop down list object
|
||||
* @return the symbol or NULL if not enabled
|
||||
*/
|
||||
lv_dropdown_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist);
|
||||
|
||||
/**
|
||||
* Get whether the ddlist highlight the last selected option and display its text or not
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_dropdown_get_show_selected(lv_obj_t * ddlist);
|
||||
lv_dir_t lv_dropdown_get_dir(const lv_obj_t * ddlist);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
|
||||
@@ -124,7 +124,7 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->format_cb = copy_ext->format_cb;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(gauge, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(gauge, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("gauge created");
|
||||
@@ -199,7 +199,7 @@ void lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int32_t value)
|
||||
|
||||
// lv_obj_invalidate(gauge);
|
||||
|
||||
lv_style_int_t pad = lv_obj_get_style_pad_inner(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_style_int_t pad = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(gauge, LV_GAUGE_PART_MAIN);
|
||||
@@ -460,14 +460,14 @@ static lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(gauge, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_mem_free(ext->values);
|
||||
ext->values = NULL;
|
||||
lv_obj_clean_style_list(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_obj_clean_style_list(gauge, LV_GAUGE_PART_MAJOR);
|
||||
_lv_obj_reset_style_list_no_refr(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
_lv_obj_reset_style_list_no_refr(gauge, LV_GAUGE_PART_MAJOR);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -513,7 +513,7 @@ static void lv_gauge_draw_labels(lv_obj_t * gauge, const lv_area_t * mask)
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t txt_pad = lv_obj_get_style_pad_inner(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t txt_pad = left;
|
||||
lv_coord_t r = (lv_obj_get_width(gauge) - left - right) / 2 - scale_width - txt_pad;
|
||||
lv_coord_t x_ofs = gauge->coords.x1 + r + left + scale_width + txt_pad;
|
||||
lv_coord_t y_ofs = gauge->coords.y1 + r + top + scale_width + txt_pad;
|
||||
@@ -569,7 +569,7 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area)
|
||||
{
|
||||
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);
|
||||
|
||||
lv_style_int_t pad = lv_obj_get_style_pad_inner(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_style_int_t pad = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_NEEDLE);
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(gauge, LV_GAUGE_PART_MAIN);
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(gauge, LV_GAUGE_PART_MAIN);
|
||||
|
||||
@@ -58,7 +58,6 @@ enum {
|
||||
LV_GAUGE_PART_MAJOR = _LV_LINEMETER_PART_VIRTUAL_LAST,
|
||||
LV_GAUGE_PART_NEEDLE,
|
||||
_LV_GAUGE_PART_VIRTUAL_LAST = _LV_LINEMETER_PART_VIRTUAL_LAST,
|
||||
_LV_GAUGE_PART_REAL_LAST = _LV_LINEMETER_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_gauge_style_t;
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->angle = 0;
|
||||
ext->zoom = LV_IMG_ZOOM_NONE;
|
||||
ext->antialias = LV_ANTIALIAS ? 1 : 0;
|
||||
ext->auto_size = 1;
|
||||
ext->offset.x = 0;
|
||||
ext->offset.y = 0;
|
||||
ext->pivot.x = 0;
|
||||
@@ -96,32 +95,25 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
if(copy == NULL) {
|
||||
lv_theme_apply(img, LV_THEME_IMAGE);
|
||||
lv_obj_set_click(img, false);
|
||||
lv_obj_set_adv_hittest(img, true); /*Images have fast hit-testing*/
|
||||
lv_obj_clear_flag(img, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_add_flag(img, LV_OBJ_FLAG_ADV_HITTEST);
|
||||
|
||||
/* Enable auto size for non screens
|
||||
* because image screens are wallpapers
|
||||
* and must be screen sized*/
|
||||
if(par != NULL) {
|
||||
ext->auto_size = 1;
|
||||
}
|
||||
else {
|
||||
ext->auto_size = 0;
|
||||
}
|
||||
if(par) lv_obj_set_size(img, LV_SIZE_AUTO, LV_SIZE_AUTO);
|
||||
}
|
||||
else {
|
||||
lv_img_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->auto_size = copy_ext->auto_size;
|
||||
ext->zoom = copy_ext->zoom;
|
||||
ext->angle = copy_ext->angle;
|
||||
ext->antialias = copy_ext->antialias;
|
||||
ext->offset.x = copy_ext->offset.x;
|
||||
ext->offset.y = copy_ext->offset.y;
|
||||
ext->pivot.x = copy_ext->pivot.x;
|
||||
ext->pivot.y = copy_ext->pivot.y;
|
||||
ext->zoom = copy_ext->zoom;
|
||||
ext->angle = copy_ext->angle;
|
||||
ext->antialias = copy_ext->antialias;
|
||||
ext->offset = copy_ext->offset;
|
||||
ext->pivot = copy_ext->pivot;
|
||||
lv_img_set_src(img, copy_ext->src);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(img, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(img, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("image created");
|
||||
@@ -142,6 +134,8 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
{
|
||||
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_invalidate(img);
|
||||
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src_img);
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
@@ -224,31 +218,14 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
|
||||
ext->pivot.x = header.w / 2;
|
||||
ext->pivot.y = header.h / 2;
|
||||
|
||||
if(lv_img_get_auto_size(img) != false) {
|
||||
lv_obj_set_size(img, ext->w, ext->h);
|
||||
}
|
||||
_lv_obj_handle_self_size_chg(img);
|
||||
|
||||
/*Provide enough room for the rotated corners*/
|
||||
if(ext->angle || ext->zoom != LV_IMG_ZOOM_NONE) lv_obj_refresh_ext_draw_pad(img);
|
||||
if(ext->angle || ext->zoom != LV_IMG_ZOOM_NONE) _lv_obj_refresh_ext_draw_pad(img);
|
||||
|
||||
lv_obj_invalidate(img);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the auto size feature.
|
||||
* If enabled the object size will be same as the picture size.
|
||||
* @param img pointer to an image
|
||||
* @param en true: auto size enable, false: auto size disable
|
||||
*/
|
||||
void lv_img_set_auto_size(lv_obj_t * img, bool en)
|
||||
{
|
||||
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
|
||||
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
ext->auto_size = (en == false ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset for the source of an image.
|
||||
* so the image will be displayed from the new origin.
|
||||
@@ -289,13 +266,13 @@ void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y)
|
||||
* Set the rotation center of the image.
|
||||
* The image will be rotated around this point
|
||||
* @param img pointer to an image object
|
||||
* @param pivot_x rotation center x of the image
|
||||
* @param pivot_y rotation center y of the image
|
||||
* @param x rotation center x of the image
|
||||
* @param y rotation center y of the image
|
||||
*/
|
||||
void lv_img_set_pivot(lv_obj_t * img, lv_coord_t pivot_x, lv_coord_t pivot_y)
|
||||
void lv_img_set_pivot(lv_obj_t * img, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
if(ext->pivot.x == pivot_x && ext->pivot.y == pivot_y) return;
|
||||
if(ext->pivot.x == x && ext->pivot.y == y) return;
|
||||
|
||||
lv_style_int_t transf_zoom = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN);
|
||||
transf_zoom = (transf_zoom * ext->zoom) >> 8;
|
||||
@@ -313,9 +290,9 @@ void lv_img_set_pivot(lv_obj_t * img, lv_coord_t pivot_x, lv_coord_t pivot_y)
|
||||
a.y2 += img->coords.y1;
|
||||
lv_obj_invalidate_area(img, &a);
|
||||
|
||||
ext->pivot.x = pivot_x;
|
||||
ext->pivot.y = pivot_y;
|
||||
lv_obj_refresh_ext_draw_pad(img);
|
||||
ext->pivot.x = x;
|
||||
ext->pivot.y = y;
|
||||
_lv_obj_refresh_ext_draw_pad(img);
|
||||
|
||||
_lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &ext->pivot);
|
||||
a.x1 += img->coords.x1;
|
||||
@@ -354,7 +331,7 @@ void lv_img_set_angle(lv_obj_t * img, int16_t angle)
|
||||
lv_obj_invalidate_area(img, &a);
|
||||
|
||||
ext->angle = angle;
|
||||
lv_obj_refresh_ext_draw_pad(img);
|
||||
_lv_obj_refresh_ext_draw_pad(img);
|
||||
|
||||
_lv_img_buf_get_transformed_area(&a, w, h, transf_angle + ext->angle, transf_zoom, &ext->pivot);
|
||||
a.x1 += img->coords.x1;
|
||||
@@ -397,7 +374,7 @@ void lv_img_set_zoom(lv_obj_t * img, uint16_t zoom)
|
||||
lv_obj_invalidate_area(img, &a);
|
||||
|
||||
ext->zoom = zoom;
|
||||
lv_obj_refresh_ext_draw_pad(img);
|
||||
_lv_obj_refresh_ext_draw_pad(img);
|
||||
|
||||
_lv_img_buf_get_transformed_area(&a, w, h, transf_angle, (transf_zoom * ext->zoom) >> 8, &ext->pivot);
|
||||
a.x1 += img->coords.x1;
|
||||
@@ -439,37 +416,6 @@ const void * lv_img_get_src(lv_obj_t * img)
|
||||
return ext->src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the file set for an image
|
||||
* @param img pointer to an image
|
||||
* @return file name
|
||||
*/
|
||||
const char * lv_img_get_file_name(const lv_obj_t * img)
|
||||
{
|
||||
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
|
||||
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
if(ext->src_type == LV_IMG_SRC_FILE)
|
||||
return ext->src;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the auto size enable attribute
|
||||
* @param img pointer to an image
|
||||
* @return true: auto size is enabled, false: auto size is disabled
|
||||
*/
|
||||
bool lv_img_get_auto_size(const lv_obj_t * img)
|
||||
{
|
||||
LV_ASSERT_OBJ(img, LV_OBJX_NAME);
|
||||
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
|
||||
return ext->auto_size == 0 ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the offset.x attribute of the img object.
|
||||
* @param img pointer to an image
|
||||
@@ -621,7 +567,7 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
|
||||
|
||||
/*If the border is drawn later disable loading its properties*/
|
||||
if(lv_obj_get_style_border_post(img, LV_OBJ_PART_MAIN)) {
|
||||
bg_dsc.border_opa = LV_OPA_TRANSP;
|
||||
bg_dsc.border_post = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -779,22 +725,21 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
|
||||
static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_img_get_style(img, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(img, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(img, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_img_get_style(img, info->part);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
|
||||
lv_mem_free(ext->src);
|
||||
ext->src = NULL;
|
||||
@@ -809,6 +754,7 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
|
||||
lv_coord_t * s = param;
|
||||
lv_style_int_t transf_zoom = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN);
|
||||
transf_zoom = (transf_zoom * ext->zoom) >> 8;
|
||||
|
||||
@@ -821,11 +767,11 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
lv_coord_t w = lv_obj_get_width(img);
|
||||
lv_coord_t h = lv_obj_get_height(img);
|
||||
_lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &ext->pivot);
|
||||
lv_coord_t pad_ori = img->ext_draw_pad;
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori - a.x1);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori - a.y1);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.x2 - w);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.y2 - h);
|
||||
lv_coord_t pad_ori = *s;
|
||||
*s = LV_MATH_MAX(*s, pad_ori - a.x1);
|
||||
*s = LV_MATH_MAX(*s, pad_ori - a.y1);
|
||||
*s = LV_MATH_MAX(*s, pad_ori + a.x2 - w);
|
||||
*s = LV_MATH_MAX(*s, pad_ori + a.y2 - h);
|
||||
}
|
||||
|
||||
/*Handle the padding of the background*/
|
||||
@@ -834,12 +780,10 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(img, LV_IMG_PART_MAIN);
|
||||
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(img, LV_IMG_PART_MAIN);
|
||||
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, left);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, right);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, top);
|
||||
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, bottom);
|
||||
|
||||
|
||||
*s = LV_MATH_MAX(*s, left);
|
||||
*s = LV_MATH_MAX(*s, right);
|
||||
*s = LV_MATH_MAX(*s, top);
|
||||
*s = LV_MATH_MAX(*s, bottom);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_HIT_TEST) {
|
||||
lv_hit_test_info_t * info = param;
|
||||
@@ -866,7 +810,12 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
|
||||
info->result = _lv_area_is_point_on(&coords, info->point, 0);
|
||||
}
|
||||
else
|
||||
info->result = lv_obj_is_point_on_coords(img, info->point);
|
||||
info->result = _lv_obj_is_click_point_on(img, info->point);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_SELF_SIZE) {
|
||||
lv_point_t * p = param;
|
||||
p->x = ext->w;
|
||||
p->y = ext->h;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@@ -41,7 +41,6 @@ typedef struct {
|
||||
lv_point_t pivot; /*rotation center of the image*/
|
||||
uint16_t zoom; /*256 means no zoom, 512 double size, 128 half size*/
|
||||
uint8_t src_type : 2; /*See: lv_img_src_t*/
|
||||
uint8_t auto_size : 1; /*1: automatically set the object size to the image size*/
|
||||
uint8_t cf : 5; /*Color format from `lv_img_color_format_t`*/
|
||||
uint8_t antialias : 1; /*Apply anti-aliasing in transformations (rotate, zoom)*/
|
||||
} lv_img_ext_t;
|
||||
@@ -75,14 +74,6 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
*/
|
||||
void lv_img_set_src(lv_obj_t * img, const void * src_img);
|
||||
|
||||
/**
|
||||
* Enable the auto size feature.
|
||||
* If enabled the object size will be same as the picture size.
|
||||
* @param img pointer to an image
|
||||
* @param en true: auto size enable, false: auto size disable
|
||||
*/
|
||||
void lv_img_set_auto_size(lv_obj_t * img, bool autosize_en);
|
||||
|
||||
/**
|
||||
* Set an offset for the source of an image.
|
||||
* so the image will be displayed from the new origin.
|
||||
@@ -103,10 +94,10 @@ void lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y);
|
||||
* Set the rotation center of the image.
|
||||
* The image will be rotated around this point
|
||||
* @param img pointer to an image object
|
||||
* @param pivot_x rotation center x of the image
|
||||
* @param pivot_y rotation center y of the image
|
||||
* @param x rotation center x of the image
|
||||
* @param y rotation center y of the image
|
||||
*/
|
||||
void lv_img_set_pivot(lv_obj_t * img, lv_coord_t pivot_x, lv_coord_t pivot_y);
|
||||
void lv_img_set_pivot(lv_obj_t * img, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the rotation angle of the image.
|
||||
@@ -146,20 +137,6 @@ void lv_img_set_antialias(lv_obj_t * img, bool antialias);
|
||||
*/
|
||||
const void * lv_img_get_src(lv_obj_t * img);
|
||||
|
||||
/**
|
||||
* Get the name of the file set for an image
|
||||
* @param img pointer to an image
|
||||
* @return file name
|
||||
*/
|
||||
const char * lv_img_get_file_name(const lv_obj_t * img);
|
||||
|
||||
/**
|
||||
* Get the auto size enable attribute
|
||||
* @param img pointer to an image
|
||||
* @return true: auto size is enabled, false: auto size is disabled
|
||||
*/
|
||||
bool lv_img_get_auto_size(const lv_obj_t * img);
|
||||
|
||||
/**
|
||||
* Get the offset.x attribute of the img object.
|
||||
* @param img pointer to an image
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
static lv_design_res_t lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param);
|
||||
static void refr_img(lv_obj_t * imgbtn);
|
||||
static lv_btn_state_t suggest_state(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
static lv_imgbtn_state_t suggest_state(lv_obj_t * imgbtn, lv_imgbtn_state_t state);
|
||||
lv_imgbtn_state_t get_state(const lv_obj_t * imgbtn);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -101,7 +102,7 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
#endif
|
||||
ext->tiled = copy_ext->tiled;
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(imgbtn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(imgbtn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("image button created");
|
||||
@@ -116,10 +117,10 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/**
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param state for which state set the new image
|
||||
* @param src pointer to an image source (a C array or path to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src)
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_imgbtn_state_t state, const void * src)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
@@ -138,7 +139,7 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
|
||||
/**
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param state for which state set the new image
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to
|
||||
* a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C
|
||||
@@ -146,7 +147,7 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path
|
||||
* to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src_tiled(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid,
|
||||
void lv_imgbtn_set_src_tiled(lv_obj_t * imgbtn, lv_imgbtn_state_t state, const void * src_left, const void * src_mid,
|
||||
const void * src_right)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
@@ -171,26 +172,6 @@ void lv_imgbtn_set_src_tiled(lv_obj_t * imgbtn, lv_btn_state_t state, const void
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state the new state of the button (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_imgbtn_set_state(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
{
|
||||
lv_btn_set_state(imgbtn, state);
|
||||
refr_img(imgbtn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the state of the image button (ON->OFF, OFF->ON)
|
||||
* @param imgbtn pointer to a image button object
|
||||
*/
|
||||
void lv_imgbtn_toggle(lv_obj_t * imgbtn)
|
||||
{
|
||||
lv_btn_toggle(imgbtn);
|
||||
refr_img(imgbtn);
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -201,7 +182,7 @@ void lv_imgbtn_toggle(lv_obj_t * imgbtn)
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to an image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_imgbtn_state_t state)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
@@ -217,7 +198,7 @@ const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the left image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_imgbtn_state_t state)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
@@ -232,7 +213,7 @@ const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the middle image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_imgbtn_state_t state)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
@@ -247,7 +228,7 @@ const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the left image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_imgbtn_state_t state)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
@@ -328,7 +309,7 @@ static lv_design_res_t lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * cli
|
||||
|
||||
/*Just draw an image*/
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
lv_btn_state_t state = suggest_state(imgbtn, lv_imgbtn_get_state(imgbtn));
|
||||
lv_imgbtn_state_t state = suggest_state(imgbtn, get_state(imgbtn));
|
||||
|
||||
/*Simply draw the middle src if no tiled*/
|
||||
if(!ext->tiled) {
|
||||
@@ -469,9 +450,10 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(imgbtn, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
/* If the style changed then the button was clicked, released etc. so probably the state was
|
||||
* changed as well Set the new image for the new state.*/
|
||||
refr_img(imgbtn);
|
||||
@@ -483,10 +465,11 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
|
||||
lv_style_int_t top = lv_obj_get_style_pad_top(imgbtn, LV_IMGBTN_PART_MAIN);
|
||||
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(imgbtn, LV_IMGBTN_PART_MAIN);
|
||||
|
||||
imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, left);
|
||||
imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, right);
|
||||
imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, top);
|
||||
imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, bottom);
|
||||
lv_coord_t * s = param;
|
||||
*s = LV_MATH_MAX(*s, left);
|
||||
*s = LV_MATH_MAX(*s, right);
|
||||
*s = LV_MATH_MAX(*s, top);
|
||||
*s = LV_MATH_MAX(*s, bottom);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {
|
||||
refr_img(imgbtn);
|
||||
@@ -501,7 +484,7 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par
|
||||
static void refr_img(lv_obj_t * imgbtn)
|
||||
{
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
lv_btn_state_t state = suggest_state(imgbtn, lv_imgbtn_get_state(imgbtn));
|
||||
lv_imgbtn_state_t state = suggest_state(imgbtn, get_state(imgbtn));
|
||||
lv_img_header_t header;
|
||||
|
||||
const void * src = ext->img_src_mid[state];
|
||||
@@ -538,28 +521,28 @@ static void refr_img(lv_obj_t * imgbtn)
|
||||
* @param state the state to convert
|
||||
* @return the suggested state
|
||||
*/
|
||||
static lv_btn_state_t suggest_state(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
static lv_imgbtn_state_t suggest_state(lv_obj_t * imgbtn, lv_imgbtn_state_t state)
|
||||
{
|
||||
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
|
||||
if(ext->img_src_mid[state] == NULL) {
|
||||
switch(state) {
|
||||
case LV_BTN_STATE_PRESSED:
|
||||
if(ext->img_src_mid[LV_BTN_STATE_RELEASED]) return LV_BTN_STATE_RELEASED;
|
||||
case LV_IMGBTN_STATE_PRESSED:
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_RELEASED]) return LV_IMGBTN_STATE_RELEASED;
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_RELEASED:
|
||||
if(ext->img_src_mid[LV_BTN_STATE_RELEASED]) return LV_BTN_STATE_RELEASED;
|
||||
case LV_IMGBTN_STATE_CHECKED_RELEASED:
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_RELEASED]) return LV_IMGBTN_STATE_RELEASED;
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_PRESSED:
|
||||
if(ext->img_src_mid[LV_BTN_STATE_CHECKED_RELEASED]) return LV_BTN_STATE_CHECKED_RELEASED;
|
||||
if(ext->img_src_mid[LV_BTN_STATE_PRESSED]) return LV_BTN_STATE_PRESSED;
|
||||
if(ext->img_src_mid[LV_BTN_STATE_RELEASED]) return LV_BTN_STATE_RELEASED;
|
||||
case LV_IMGBTN_STATE_CHECKED_PRESSED:
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_CHECKED_RELEASED]) return LV_IMGBTN_STATE_CHECKED_RELEASED;
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_PRESSED]) return LV_IMGBTN_STATE_PRESSED;
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_RELEASED]) return LV_IMGBTN_STATE_RELEASED;
|
||||
break;
|
||||
case LV_BTN_STATE_DISABLED:
|
||||
if(ext->img_src_mid[LV_BTN_STATE_RELEASED]) return LV_BTN_STATE_RELEASED;
|
||||
case LV_IMGBTN_STATE_DISABLED:
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_RELEASED]) return LV_IMGBTN_STATE_RELEASED;
|
||||
break;
|
||||
case LV_BTN_STATE_CHECKED_DISABLED:
|
||||
if(ext->img_src_mid[LV_BTN_STATE_CHECKED_RELEASED]) return LV_BTN_STATE_CHECKED_RELEASED;
|
||||
if(ext->img_src_mid[LV_BTN_STATE_RELEASED]) return LV_BTN_STATE_RELEASED;
|
||||
case LV_IMGBTN_STATE_CHECKED_DISABLED:
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_CHECKED_RELEASED]) return LV_IMGBTN_STATE_CHECKED_RELEASED;
|
||||
if(ext->img_src_mid[LV_IMGBTN_STATE_RELEASED]) return LV_IMGBTN_STATE_RELEASED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -569,4 +552,25 @@ static lv_btn_state_t suggest_state(lv_obj_t * imgbtn, lv_btn_state_t state)
|
||||
return state;
|
||||
}
|
||||
|
||||
lv_imgbtn_state_t get_state(const lv_obj_t * imgbtn)
|
||||
{
|
||||
LV_ASSERT_OBJ(imgbtn, LV_OBJX_NAME);
|
||||
|
||||
lv_state_t obj_state = lv_obj_get_state(imgbtn);
|
||||
|
||||
if(obj_state & LV_STATE_DISABLED) {
|
||||
if(obj_state & LV_STATE_CHECKED) return LV_IMGBTN_STATE_CHECKED_DISABLED;
|
||||
else return LV_IMGBTN_STATE_DISABLED;
|
||||
}
|
||||
|
||||
if(obj_state & LV_STATE_CHECKED) {
|
||||
if(obj_state & LV_STATE_PRESSED) return LV_IMGBTN_STATE_CHECKED_PRESSED;
|
||||
else return LV_IMGBTN_STATE_CHECKED_RELEASED;
|
||||
}
|
||||
else {
|
||||
if(obj_state & LV_STATE_PRESSED) return LV_IMGBTN_STATE_PRESSED;
|
||||
else return LV_IMGBTN_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,11 +17,6 @@ extern "C" {
|
||||
|
||||
#if LV_USE_IMGBTN != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_BTN == 0
|
||||
#error "lv_imgbtn: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_btn.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
@@ -29,18 +24,26 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
typedef enum {
|
||||
LV_IMGBTN_STATE_RELEASED,
|
||||
LV_IMGBTN_STATE_PRESSED,
|
||||
LV_IMGBTN_STATE_DISABLED,
|
||||
LV_IMGBTN_STATE_CHECKED_RELEASED,
|
||||
LV_IMGBTN_STATE_CHECKED_PRESSED,
|
||||
LV_IMGBTN_STATE_CHECKED_DISABLED,
|
||||
_LV_IMGBTN_STATE_NUM,
|
||||
}lv_imgbtn_state_t;
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of image button*/
|
||||
typedef struct {
|
||||
lv_btn_ext_t btn; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
const void * img_src_mid[_LV_BTN_STATE_LAST]; /*Store center images to each state*/
|
||||
const void * img_src_mid[_LV_IMGBTN_STATE_NUM]; /*Store center images to each state*/
|
||||
#if LV_IMGBTN_TILED
|
||||
const void * img_src_left[_LV_BTN_STATE_LAST]; /*Store left side images to each state*/
|
||||
const void * img_src_right[_LV_BTN_STATE_LAST]; /*Store right side images to each state*/
|
||||
const void * img_src_left[_LV_IMGBTN_STATE_NUM]; /*Store left side images to each state*/
|
||||
const void * img_src_right[_LV_IMGBTN_STATE_NUM]; /*Store right side images to each state*/
|
||||
#endif
|
||||
lv_img_cf_t act_cf; /*Color format of the currently active image*/
|
||||
uint8_t tiled : 1; /*1: the middle src will be repeated to fill the user defined width*/
|
||||
@@ -76,16 +79,16 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
/**
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param state for which state set the new image
|
||||
* @param src pointer to an image source (a C array or path to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src);
|
||||
void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_imgbtn_state_t state, const void * src);
|
||||
|
||||
#if LV_IMGBTN_TILED
|
||||
/**
|
||||
* Set images for a state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state for which state set the new image (from `lv_btn_state_t`) `
|
||||
* @param state for which state set the new image
|
||||
* @param src_left pointer to an image source for the left side of the button (a C array or path to
|
||||
* a file)
|
||||
* @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C
|
||||
@@ -93,35 +96,11 @@ void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src
|
||||
* @param src_right pointer to an image source for the right side of the button (a C array or path
|
||||
* to a file)
|
||||
*/
|
||||
void lv_imgbtn_set_src_tiled(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid,
|
||||
void lv_imgbtn_set_src_tiled(lv_obj_t * imgbtn, lv_imgbtn_state_t state, const void * src_left, const void * src_mid,
|
||||
const void * src_right);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the state of the image button
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param state the new state of the button (from lv_btn_state_t enum)
|
||||
*/
|
||||
void lv_imgbtn_set_state(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
|
||||
/**
|
||||
* Toggle the state of the image button (ON->OFF, OFF->ON)
|
||||
* @param imgbtn pointer to a image button object
|
||||
*/
|
||||
void lv_imgbtn_toggle(lv_obj_t * imgbtn);
|
||||
|
||||
/**
|
||||
* Enable the toggled states. On release the button will change from/to toggled state.
|
||||
* @param imgbtn pointer to an image button object
|
||||
* @param tgl true: enable toggled states, false: disable
|
||||
*/
|
||||
static inline void lv_imgbtn_set_checkable(lv_obj_t * imgbtn, bool tgl)
|
||||
{
|
||||
lv_btn_set_checkable(imgbtn, tgl);
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -133,7 +112,7 @@ static inline void lv_imgbtn_set_checkable(lv_obj_t * imgbtn, bool tgl)
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to an image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_imgbtn_state_t state);
|
||||
|
||||
#else
|
||||
|
||||
@@ -143,7 +122,7 @@ const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the left image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_imgbtn_state_t state);
|
||||
|
||||
/**
|
||||
* Get the middle image in a given state
|
||||
@@ -151,7 +130,7 @@ const void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the middle image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_imgbtn_state_t state);
|
||||
|
||||
/**
|
||||
* Get the right image in a given state
|
||||
@@ -159,28 +138,10 @@ const void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
* @param state the state where to get the image (from `lv_btn_state_t`) `
|
||||
* @return pointer to the left image source (a C array or path to a file)
|
||||
*/
|
||||
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state);
|
||||
const void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_imgbtn_state_t state);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Get the current state of the image button
|
||||
* @param imgbtn pointer to a image button object
|
||||
* @return the state of the button (from lv_btn_state_t enum)
|
||||
*/
|
||||
static inline lv_btn_state_t lv_imgbtn_get_state(const lv_obj_t * imgbtn)
|
||||
{
|
||||
return lv_btn_get_state(imgbtn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the toggle enable attribute of the image button
|
||||
* @param imgbtn pointer to a image button object
|
||||
* @return true: toggle enabled, false: disabled
|
||||
*/
|
||||
static inline bool lv_imgbtn_get_checkable(const lv_obj_t * imgbtn)
|
||||
{
|
||||
return lv_btn_get_checkable(imgbtn);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
|
||||
@@ -1,481 +0,0 @@
|
||||
|
||||
/**
|
||||
* @file lv_kb.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_keyboard.h"
|
||||
#if LV_USE_KEYBOARD != 0
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "lv_textarea.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_keyboard"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_keyboard_signal(lv_obj_t * kb, lv_signal_t sign, void * param);
|
||||
static void lv_keyboard_update_map(lv_obj_t * kb);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
/* clang-format off */
|
||||
static const char * const default_kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n",
|
||||
"_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t default_kb_ctrl_lc_map[] = {
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
||||
};
|
||||
|
||||
static const char * const default_kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n",
|
||||
"_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t default_kb_ctrl_uc_map[] = {
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
||||
};
|
||||
|
||||
static const char * const default_kb_map_spec[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
|
||||
"\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
|
||||
LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t default_kb_ctrl_spec_map[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
||||
};
|
||||
|
||||
static const char * const default_kb_map_num[] = {"1", "2", "3", LV_SYMBOL_CLOSE, "\n",
|
||||
"4", "5", "6", LV_SYMBOL_OK, "\n",
|
||||
"7", "8", "9", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"+/-", "0", ".", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, ""
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t default_kb_ctrl_num_map[] = {
|
||||
1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 2,
|
||||
1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 2,
|
||||
1, 1, 1, 2,
|
||||
1, 1, 1, 1, 1
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static const char * * kb_map[4] = {
|
||||
(const char * *)default_kb_map_lc,
|
||||
(const char * *)default_kb_map_uc,
|
||||
(const char * *)default_kb_map_spec,
|
||||
(const char * *)default_kb_map_num
|
||||
};
|
||||
static const lv_btnmatrix_ctrl_t * kb_ctrl[4] = {
|
||||
default_kb_ctrl_lc_map,
|
||||
default_kb_ctrl_uc_map,
|
||||
default_kb_ctrl_spec_map,
|
||||
default_kb_ctrl_num_map
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a keyboard objects
|
||||
* @param par pointer to an object, it will be the parent of the new keyboard
|
||||
* @param copy pointer to a keyboard object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created keyboard
|
||||
*/
|
||||
lv_obj_t * lv_keyboard_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("keyboard create started");
|
||||
|
||||
/*Create the ancestor of keyboard*/
|
||||
lv_obj_t * kb = lv_btnmatrix_create(par, copy);
|
||||
LV_ASSERT_MEM(kb);
|
||||
if(kb == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(kb);
|
||||
|
||||
/*Allocate the keyboard type specific extended data*/
|
||||
lv_keyboard_ext_t * ext = lv_obj_allocate_ext_attr(kb, sizeof(lv_keyboard_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(kb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->ta = NULL;
|
||||
ext->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
|
||||
ext->cursor_mng = 0;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(kb, lv_keyboard_signal);
|
||||
|
||||
/*Init the new keyboard keyboard*/
|
||||
if(copy == NULL) {
|
||||
/* Set a size which fits into the parent.
|
||||
* Don't use `par` directly because if the window is created on a page it is moved to the
|
||||
* scrollable so the parent has changed */
|
||||
lv_obj_set_size(kb, lv_obj_get_width_fit(lv_obj_get_parent(kb)),
|
||||
lv_obj_get_height_fit(lv_obj_get_parent(kb)) / 2);
|
||||
lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
lv_obj_set_event_cb(kb, lv_keyboard_def_event_cb);
|
||||
lv_obj_set_base_dir(kb, LV_BIDI_DIR_LTR);
|
||||
lv_obj_add_protect(kb, LV_PROTECT_CLICK_FOCUS);
|
||||
|
||||
lv_btnmatrix_set_map(kb, kb_map[ext->mode]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[ext->mode]);
|
||||
|
||||
lv_theme_apply(kb, LV_THEME_KEYBOARD);
|
||||
}
|
||||
/*Copy an existing keyboard*/
|
||||
else {
|
||||
lv_keyboard_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->ta = copy_ext->ta;
|
||||
ext->mode = copy_ext->mode;
|
||||
ext->cursor_mng = copy_ext->cursor_mng;
|
||||
|
||||
lv_btnmatrix_set_map(kb, kb_map[ext->mode]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[ext->mode]);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
// lv_obj_refresh_style(new_kb);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("keyboard created");
|
||||
|
||||
return kb;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param ta pointer to a Text Area object to write there
|
||||
*/
|
||||
void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
if(ta) {
|
||||
LV_ASSERT_OBJ(ta, "lv_textarea");
|
||||
}
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
|
||||
/*Hide the cursor of the old Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, true);
|
||||
}
|
||||
|
||||
ext->ta = ta;
|
||||
|
||||
/*Show the cursor of the new Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new a mode (text or number map)
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param mode the mode from 'lv_keyboard_mode_t'
|
||||
*/
|
||||
void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
if(ext->mode == mode) return;
|
||||
|
||||
ext->mode = mode;
|
||||
lv_btnmatrix_set_map(kb, kb_map[mode]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[mode]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically hide or show the cursor of Text Area
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param en true: show cursor on the current text area, false: hide cursor
|
||||
*/
|
||||
void lv_keyboard_set_cursor_manage(lv_obj_t * kb, bool en)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
if(ext->cursor_mng == en) return;
|
||||
|
||||
ext->cursor_mng = en == false ? 0 : 1;
|
||||
|
||||
if(ext->ta) {
|
||||
|
||||
if(ext->cursor_mng) {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, false);
|
||||
}
|
||||
else {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new map for the keyboard
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param mode keyboard map to alter 'lv_keyboard_mode_t'
|
||||
* @param map pointer to a string array to describe the map.
|
||||
* See 'lv_btnmatrix_set_map()' for more info.
|
||||
*/
|
||||
void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[])
|
||||
{
|
||||
kb_map[mode] = map;
|
||||
lv_keyboard_update_map(kb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the button control map (hidden, disabled etc.) for the keyboard. The
|
||||
* control map array will be copied and so may be deallocated after this
|
||||
* function returns.
|
||||
* @param kb pointer to a keyboard object
|
||||
* @param mode keyboard ctrl map to alter 'lv_keyboard_mode_t'
|
||||
* @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes.
|
||||
* See: `lv_btnmatrix_set_ctrl_map` for more details.
|
||||
*/
|
||||
void lv_keyboard_set_ctrl_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const lv_btnmatrix_ctrl_t ctrl_map[])
|
||||
{
|
||||
kb_ctrl[mode] = ctrl_map;
|
||||
lv_keyboard_update_map(kb);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return pointer to the assigned Text Area object
|
||||
*/
|
||||
lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
return ext->ta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new a mode (text or number map)
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return the current mode from 'lv_keyboard_mode_t'
|
||||
*/
|
||||
lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
return ext->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current cursor manage mode.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return true: show cursor on the current text area, false: hide cursor
|
||||
*/
|
||||
bool lv_keyboard_get_cursor_manage(const lv_obj_t * kb)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
return ext->cursor_mng == 0 ? false : true;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Default keyboard event to add characters to the Text area and change the map.
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the
|
||||
* button clicks
|
||||
* @param kb pointer to a keyboard
|
||||
* @param event the triggering event
|
||||
*/
|
||||
void lv_keyboard_def_event_cb(lv_obj_t * kb, lv_event_t event)
|
||||
{
|
||||
LV_ASSERT_OBJ(kb, LV_OBJX_NAME);
|
||||
|
||||
if(event != LV_EVENT_VALUE_CHANGED) return;
|
||||
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
uint16_t btn_id = lv_btnmatrix_get_active_btn(kb);
|
||||
if(btn_id == LV_BTNMATRIX_BTN_NONE) return;
|
||||
if(lv_btnmatrix_get_btn_ctrl(kb, btn_id, LV_BTNMATRIX_CTRL_HIDDEN | LV_BTNMATRIX_CTRL_DISABLED)) return;
|
||||
if(lv_btnmatrix_get_btn_ctrl(kb, btn_id, LV_BTNMATRIX_CTRL_NO_REPEAT) && event == LV_EVENT_LONG_PRESSED_REPEAT) return;
|
||||
|
||||
const char * txt = lv_btnmatrix_get_active_btn_text(kb);
|
||||
if(txt == NULL) return;
|
||||
|
||||
/*Do the corresponding action according to the text of the button*/
|
||||
if(strcmp(txt, "abc") == 0) {
|
||||
ext->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
|
||||
lv_btnmatrix_set_map(kb, kb_map[LV_KEYBOARD_MODE_TEXT_LOWER]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[LV_KEYBOARD_MODE_TEXT_LOWER]);
|
||||
return;
|
||||
}
|
||||
else if(strcmp(txt, "ABC") == 0) {
|
||||
ext->mode = LV_KEYBOARD_MODE_TEXT_UPPER;
|
||||
lv_btnmatrix_set_map(kb, kb_map[LV_KEYBOARD_MODE_TEXT_UPPER]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[LV_KEYBOARD_MODE_TEXT_UPPER]);
|
||||
return;
|
||||
}
|
||||
else if(strcmp(txt, "1#") == 0) {
|
||||
ext->mode = LV_KEYBOARD_MODE_SPECIAL;
|
||||
lv_btnmatrix_set_map(kb, kb_map[LV_KEYBOARD_MODE_SPECIAL]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[LV_KEYBOARD_MODE_SPECIAL]);
|
||||
return;
|
||||
}
|
||||
else if(strcmp(txt, LV_SYMBOL_CLOSE) == 0) {
|
||||
if(kb->event_cb != lv_keyboard_def_event_cb) {
|
||||
lv_res_t res = lv_event_send(kb, LV_EVENT_CANCEL, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
}
|
||||
else {
|
||||
lv_keyboard_set_textarea(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
lv_obj_del(kb);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(strcmp(txt, LV_SYMBOL_OK) == 0) {
|
||||
if(kb->event_cb != lv_keyboard_def_event_cb) {
|
||||
lv_res_t res = lv_event_send(kb, LV_EVENT_APPLY, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
}
|
||||
else {
|
||||
lv_keyboard_set_textarea(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*Add the characters to the text area if set*/
|
||||
if(ext->ta == NULL) return;
|
||||
|
||||
if(strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0)
|
||||
lv_textarea_add_char(ext->ta, '\n');
|
||||
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)
|
||||
lv_textarea_cursor_left(ext->ta);
|
||||
else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0)
|
||||
lv_textarea_cursor_right(ext->ta);
|
||||
else if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0)
|
||||
lv_textarea_del_char(ext->ta);
|
||||
else if(strcmp(txt, "+/-") == 0) {
|
||||
uint16_t cur = lv_textarea_get_cursor_pos(ext->ta);
|
||||
const char * ta_txt = lv_textarea_get_text(ext->ta);
|
||||
if(ta_txt[0] == '-') {
|
||||
lv_textarea_set_cursor_pos(ext->ta, 1);
|
||||
lv_textarea_del_char(ext->ta);
|
||||
lv_textarea_add_char(ext->ta, '+');
|
||||
lv_textarea_set_cursor_pos(ext->ta, cur);
|
||||
}
|
||||
else if(ta_txt[0] == '+') {
|
||||
lv_textarea_set_cursor_pos(ext->ta, 1);
|
||||
lv_textarea_del_char(ext->ta);
|
||||
lv_textarea_add_char(ext->ta, '-');
|
||||
lv_textarea_set_cursor_pos(ext->ta, cur);
|
||||
}
|
||||
else {
|
||||
lv_textarea_set_cursor_pos(ext->ta, 0);
|
||||
lv_textarea_add_char(ext->ta, '-');
|
||||
lv_textarea_set_cursor_pos(ext->ta, cur + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_textarea_add_text(ext->ta, txt);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the keyboard
|
||||
* @param kb pointer to a keyboard object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_keyboard_signal(lv_obj_t * kb, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(kb, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
else if(sign == LV_SIGNAL_FOCUS) {
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
/*Show the cursor of the Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, false);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
/*Show the cursor of the Text area if cursor management is enabled*/
|
||||
if(ext->ta && ext->cursor_mng) {
|
||||
lv_textarea_set_cursor_hidden(ext->ta, true);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the key map for the current mode
|
||||
* @param kb pointer to a keyboard object
|
||||
*/
|
||||
static void lv_keyboard_update_map(lv_obj_t * kb)
|
||||
{
|
||||
lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb);
|
||||
lv_btnmatrix_set_map(kb, kb_map[ext->mode]);
|
||||
lv_btnmatrix_set_ctrl_map(kb, kb_ctrl[ext->mode]);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,180 +0,0 @@
|
||||
/**
|
||||
* @file lv_keyboard.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_KEYBOARD_H
|
||||
#define LV_KEYBOARD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_KEYBOARD != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_BTNMATRIX == 0
|
||||
#error "lv_kb: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BTNMATRIX 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_TEXTAREA == 0
|
||||
#error "lv_kb: lv_ta is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_btnmatrix.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_KEYBOARD_CTRL_BTN_FLAGS (LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_CLICK_TRIG)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Current keyboard mode. */
|
||||
enum {
|
||||
LV_KEYBOARD_MODE_TEXT_LOWER,
|
||||
LV_KEYBOARD_MODE_TEXT_UPPER,
|
||||
LV_KEYBOARD_MODE_SPECIAL,
|
||||
LV_KEYBOARD_MODE_NUM,
|
||||
};
|
||||
typedef uint8_t lv_keyboard_mode_t;
|
||||
|
||||
/*Data of keyboard*/
|
||||
typedef struct {
|
||||
lv_btnmatrix_ext_t btnm; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t * ta; /*Pointer to the assigned text area*/
|
||||
lv_keyboard_mode_t mode; /*Key map type*/
|
||||
uint8_t cursor_mng : 1; /*1: automatically show/hide cursor when a text area is assigned or left*/
|
||||
} lv_keyboard_ext_t;
|
||||
|
||||
enum {
|
||||
LV_KEYBOARD_PART_BG,
|
||||
LV_KEYBOARD_PART_BTN,
|
||||
};
|
||||
typedef uint8_t lv_keyboard_style_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a keyboard objects
|
||||
* @param par pointer to an object, it will be the parent of the new keyboard
|
||||
* @param copy pointer to a keyboard object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created keyboard
|
||||
*/
|
||||
lv_obj_t * lv_keyboard_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param ta pointer to a Text Area object to write there
|
||||
*/
|
||||
void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta);
|
||||
|
||||
/**
|
||||
* Set a new a mode (text or number map)
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param mode the mode from 'lv_keyboard_mode_t'
|
||||
*/
|
||||
void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode);
|
||||
|
||||
/**
|
||||
* Automatically hide or show the cursor of the current Text Area
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param en true: show cursor on the current text area, false: hide cursor
|
||||
*/
|
||||
void lv_keyboard_set_cursor_manage(lv_obj_t * kb, bool en);
|
||||
|
||||
/**
|
||||
* Set a new map for the keyboard
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @param mode keyboard map to alter 'lv_keyboard_mode_t'
|
||||
* @param map pointer to a string array to describe the map.
|
||||
* See 'lv_btnmatrix_set_map()' for more info.
|
||||
*/
|
||||
void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[]);
|
||||
|
||||
/**
|
||||
* Set the button control map (hidden, disabled etc.) for the keyboard. The
|
||||
* control map array will be copied and so may be deallocated after this
|
||||
* function returns.
|
||||
* @param kb pointer to a keyboard object
|
||||
* @param mode keyboard ctrl map to alter 'lv_keyboard_mode_t'
|
||||
* @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes.
|
||||
* See: `lv_btnmatrix_set_ctrl_map` for more details.
|
||||
*/
|
||||
void lv_keyboard_set_ctrl_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const lv_btnmatrix_ctrl_t ctrl_map[]);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return pointer to the assigned Text Area object
|
||||
*/
|
||||
lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb);
|
||||
|
||||
/**
|
||||
* Set a new a mode (text or number map)
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return the current mode from 'lv_keyboard_mode_t'
|
||||
*/
|
||||
lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb);
|
||||
|
||||
/**
|
||||
* Get the current cursor manage mode.
|
||||
* @param kb pointer to a Keyboard object
|
||||
* @return true: show cursor on the current text area, false: hide cursor
|
||||
*/
|
||||
bool lv_keyboard_get_cursor_manage(const lv_obj_t * kb);
|
||||
|
||||
/**
|
||||
* Get the current map of a keyboard
|
||||
* @param kb pointer to a keyboard object
|
||||
* @return the current map
|
||||
*/
|
||||
static inline const char ** lv_keyboard_get_map_array(const lv_obj_t * kb)
|
||||
{
|
||||
return lv_btnmatrix_get_map_array(kb);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Default keyboard event to add characters to the Text area and change the map.
|
||||
* If a custom `event_cb` is added to the keyboard this function be called from it to handle the
|
||||
* button clicks
|
||||
* @param kb pointer to a keyboard
|
||||
* @param event the triggering event
|
||||
*/
|
||||
void lv_keyboard_def_event_cb(lv_obj_t * kb, lv_event_t event);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_KEYBOARD*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_KEYBOARD_H*/
|
||||
@@ -69,16 +69,17 @@ static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**
|
||||
* Create a label objects
|
||||
* @param par pointer to an object, it will be the parent of the new label
|
||||
* @param copy pointer to a label object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new label
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other label to copy.
|
||||
* @return pointer to the created button
|
||||
*/
|
||||
lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("label create started");
|
||||
|
||||
/*Create a basic object*/
|
||||
lv_obj_t * new_label = lv_obj_create(par, copy);
|
||||
lv_obj_t * new_label = lv_obj_create(parent, copy);
|
||||
LV_ASSERT_MEM(new_label);
|
||||
if(new_label == NULL) return NULL;
|
||||
|
||||
@@ -119,49 +120,14 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->dot.tmp_ptr = NULL;
|
||||
ext->dot_tmp_alloc = 0;
|
||||
|
||||
|
||||
lv_obj_set_design_cb(new_label, lv_label_design);
|
||||
lv_obj_set_signal_cb(new_label, lv_label_signal);
|
||||
|
||||
/*Init the new label*/
|
||||
if(copy == NULL) {
|
||||
lv_theme_apply(new_label, LV_THEME_LABEL);
|
||||
lv_obj_set_click(new_label, false);
|
||||
lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND);
|
||||
lv_label_set_text(new_label, "Text");
|
||||
}
|
||||
/*Copy 'copy' if not NULL*/
|
||||
else {
|
||||
lv_label_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
lv_label_set_long_mode(new_label, lv_label_get_long_mode(copy));
|
||||
lv_label_set_recolor(new_label, lv_label_get_recolor(copy));
|
||||
lv_label_set_align(new_label, lv_label_get_align(copy));
|
||||
if(copy_ext->static_txt == 0)
|
||||
lv_label_set_text(new_label, lv_label_get_text(copy));
|
||||
else
|
||||
lv_label_set_text_static(new_label, lv_label_get_text(copy));
|
||||
|
||||
/*In DOT mode save the text byte-to-byte because a '\0' can be in the middle*/
|
||||
if(copy_ext->long_mode == LV_LABEL_LONG_DOT) {
|
||||
ext->text = lv_mem_realloc(ext->text, _lv_mem_get_size(copy_ext->text));
|
||||
LV_ASSERT_MEM(ext->text);
|
||||
if(ext->text == NULL) return NULL;
|
||||
_lv_memcpy(ext->text, copy_ext->text, _lv_mem_get_size(copy_ext->text));
|
||||
}
|
||||
|
||||
if(copy_ext->dot_tmp_alloc && copy_ext->dot.tmp_ptr) {
|
||||
uint32_t len = (uint32_t)strlen(copy_ext->dot.tmp_ptr);
|
||||
lv_label_set_dot_tmp(new_label, ext->dot.tmp_ptr, len);
|
||||
}
|
||||
else {
|
||||
_lv_memcpy(ext->dot.tmp, copy_ext->dot.tmp, sizeof(ext->dot.tmp));
|
||||
}
|
||||
ext->dot_tmp_alloc = copy_ext->dot_tmp_alloc;
|
||||
ext->dot_end = copy_ext->dot_end;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_label, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
lv_theme_apply(new_label, LV_THEME_LABEL);
|
||||
lv_obj_clear_flag(new_label, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND);
|
||||
lv_label_set_text(new_label, "Text");
|
||||
|
||||
LV_LOG_INFO("label created");
|
||||
|
||||
@@ -1361,7 +1327,7 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(label, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
|
||||
@@ -111,11 +111,12 @@ typedef uint8_t lv_label_part_t;
|
||||
|
||||
/**
|
||||
* Create a label objects
|
||||
* @param par pointer to an object, it will be the parent of the new label
|
||||
* @param copy pointer to a button object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new label
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other label to copy.
|
||||
* @return pointer to the created button
|
||||
*/
|
||||
lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
lv_obj_t * lv_label_create(lv_obj_t * parent, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
/**
|
||||
* @file lv_led.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_led.h"
|
||||
#if LV_USE_LED != 0
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_led"
|
||||
|
||||
#define LV_LED_WIDTH_DEF (LV_DPI / 3)
|
||||
#define LV_LED_HEIGHT_DEF (LV_DPI / 3)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_design_res_t lv_led_design(lv_obj_t * led, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_led_signal(lv_obj_t * led, lv_signal_t sign, void * param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a led objects
|
||||
* @param par pointer to an object, it will be the parent of the new led
|
||||
* @param copy pointer to a led object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created led
|
||||
*/
|
||||
lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("led create started");
|
||||
|
||||
/*Create the ancestor basic object*/
|
||||
lv_obj_t * led = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(led);
|
||||
if(led == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(led);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(led);
|
||||
|
||||
/*Allocate the object type specific extended data*/
|
||||
lv_led_ext_t * ext = lv_obj_allocate_ext_attr(led, sizeof(lv_led_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(led);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext->bright = LV_LED_BRIGHT_MAX;
|
||||
|
||||
lv_obj_set_signal_cb(led, lv_led_signal);
|
||||
lv_obj_set_design_cb(led, lv_led_design);
|
||||
|
||||
/*Init the new led object*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_size(led, LV_LED_WIDTH_DEF, LV_LED_HEIGHT_DEF);
|
||||
|
||||
lv_theme_apply(led, LV_THEME_LED);
|
||||
}
|
||||
/*Copy an existing object*/
|
||||
else {
|
||||
lv_led_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->bright = copy_ext->bright;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(led, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("led created");
|
||||
|
||||
return led;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the brightness of a LED object
|
||||
* @param led pointer to a LED object
|
||||
* @param bright LV_LED_BRIGHT_MIN (max. dark) ... LV_LED_BRIGHT_MAX (max. light)
|
||||
*/
|
||||
void lv_led_set_bright(lv_obj_t * led, uint8_t bright)
|
||||
{
|
||||
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
|
||||
|
||||
/*Set the brightness*/
|
||||
lv_led_ext_t * ext = lv_obj_get_ext_attr(led);
|
||||
if(ext->bright == bright) return;
|
||||
|
||||
if(bright <= LV_LED_BRIGHT_MIN) bright = LV_LED_BRIGHT_MIN;
|
||||
if(bright >= LV_LED_BRIGHT_MAX) bright = LV_LED_BRIGHT_MAX;
|
||||
|
||||
ext->bright = bright;
|
||||
|
||||
/*Invalidate the object there fore it will be redrawn*/
|
||||
lv_obj_invalidate(led);
|
||||
}
|
||||
|
||||
/**
|
||||
* Light on a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_on(lv_obj_t * led)
|
||||
{
|
||||
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
|
||||
|
||||
lv_led_set_bright(led, LV_LED_BRIGHT_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Light off a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_off(lv_obj_t * led)
|
||||
{
|
||||
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
|
||||
|
||||
lv_led_set_bright(led, LV_LED_BRIGHT_MIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the state of a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_toggle(lv_obj_t * led)
|
||||
{
|
||||
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
|
||||
|
||||
uint8_t bright = lv_led_get_bright(led);
|
||||
if(bright > (LV_LED_BRIGHT_MIN + LV_LED_BRIGHT_MAX) >> 1)
|
||||
lv_led_off(led);
|
||||
else
|
||||
lv_led_on(led);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the brightness of a LEd object
|
||||
* @param led pointer to LED object
|
||||
* @return bright 0 (max. dark) ... 255 (max. light)
|
||||
*/
|
||||
uint8_t lv_led_get_bright(const lv_obj_t * led)
|
||||
{
|
||||
LV_ASSERT_OBJ(led, LV_OBJX_NAME);
|
||||
|
||||
lv_led_ext_t * ext = lv_obj_get_ext_attr(led);
|
||||
return ext->bright;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the leds
|
||||
* @param led pointer to an object
|
||||
* @param clip_area 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 an element of `lv_design_res_t`
|
||||
*/
|
||||
static lv_design_res_t lv_led_design(lv_obj_t * led, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
/*Return false if the object is not covers the clip_area area*/
|
||||
return ancestor_design(led, clip_area, mode);
|
||||
}
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/*Make darker colors in a temporary style according to the brightness*/
|
||||
lv_led_ext_t * ext = lv_obj_get_ext_attr(led);
|
||||
|
||||
lv_draw_rect_dsc_t rect_dsc;
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
lv_obj_init_draw_rect_dsc(led, LV_LED_PART_MAIN, &rect_dsc);
|
||||
|
||||
/*Mix. the color with black proportionally with brightness*/
|
||||
rect_dsc.bg_color = lv_color_mix(rect_dsc.bg_color, LV_COLOR_BLACK, ext->bright);
|
||||
rect_dsc.bg_grad_color = lv_color_mix(rect_dsc.bg_grad_color, LV_COLOR_BLACK, ext->bright);
|
||||
rect_dsc.border_color = lv_color_mix(rect_dsc.border_color, LV_COLOR_BLACK, ext->bright);
|
||||
rect_dsc.shadow_color = lv_color_mix(rect_dsc.shadow_color, LV_COLOR_BLACK, ext->bright);
|
||||
|
||||
/*Set the current shadow width according to brightness proportionally between LV_LED_BRIGHT_OFF
|
||||
* and LV_LED_BRIGHT_ON*/
|
||||
rect_dsc.shadow_width = ((ext->bright - LV_LED_BRIGHT_MIN) * rect_dsc.shadow_width) /
|
||||
(LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN);
|
||||
rect_dsc.shadow_spread = ((ext->bright - LV_LED_BRIGHT_MIN) * rect_dsc.shadow_spread) /
|
||||
(LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN);
|
||||
|
||||
lv_draw_rect(&led->coords, clip_area, &rect_dsc);
|
||||
}
|
||||
return LV_DESIGN_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the led
|
||||
* @param led pointer to a led object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_led_signal(lv_obj_t * led, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(led, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_led";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @file lv_led.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LED_H
|
||||
#define LV_LED_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_LED != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Data of led*/
|
||||
typedef struct {
|
||||
/*No inherited ext.*/
|
||||
/*New data for this type */
|
||||
uint8_t bright; /*Current brightness of the LED (0..255)*/
|
||||
} lv_led_ext_t;
|
||||
|
||||
/*Parts of LED*/
|
||||
enum {
|
||||
LV_LED_PART_MAIN = LV_OBJ_PART_MAIN,
|
||||
};
|
||||
typedef uint8_t lv_led_part_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a led objects
|
||||
* @param par pointer to an object, it will be the parent of the new led
|
||||
* @param copy pointer to a led object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created led
|
||||
*/
|
||||
lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/**
|
||||
* Set the brightness of a LED object
|
||||
* @param led pointer to a LED object
|
||||
* @param bright LV_LED_BRIGHT_MIN (max. dark) ... LV_LED_BRIGHT_MAX (max. light)
|
||||
*/
|
||||
void lv_led_set_bright(lv_obj_t * led, uint8_t bright);
|
||||
|
||||
/**
|
||||
* Light on a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_on(lv_obj_t * led);
|
||||
|
||||
/**
|
||||
* Light off a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_off(lv_obj_t * led);
|
||||
|
||||
/**
|
||||
* Toggle the state of a LED
|
||||
* @param led pointer to a LED object
|
||||
*/
|
||||
void lv_led_toggle(lv_obj_t * led);
|
||||
|
||||
/**
|
||||
* Get the brightness of a LEd object
|
||||
* @param led pointer to LED object
|
||||
* @return bright 0 (max. dark) ... 255 (max. light)
|
||||
*/
|
||||
uint8_t lv_led_get_bright(const lv_obj_t * led);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LED*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LED_H*/
|
||||
@@ -71,7 +71,6 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
ext->point_num = 0;
|
||||
ext->point_array = NULL;
|
||||
ext->auto_size = 1;
|
||||
ext->y_inv = 0;
|
||||
|
||||
lv_obj_set_design_cb(line, lv_line_design);
|
||||
@@ -79,23 +78,19 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new line*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_size(line, LV_DPI,
|
||||
LV_DPI); /*Auto size is enables, but set default size until no points are added*/
|
||||
|
||||
lv_obj_set_click(line, false);
|
||||
lv_obj_set_size(line, LV_SIZE_AUTO, LV_SIZE_AUTO);
|
||||
lv_obj_clear_flag(line, LV_OBJ_FLAG_CLICKABLE);
|
||||
|
||||
lv_theme_apply(line, LV_THEME_LINE);
|
||||
}
|
||||
/*Copy an existing object*/
|
||||
else {
|
||||
lv_line_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
lv_line_set_auto_size(line, lv_line_get_auto_size(copy));
|
||||
lv_line_set_y_invert(line, lv_line_get_y_invert(copy));
|
||||
lv_line_set_auto_size(line, lv_line_get_auto_size(copy));
|
||||
lv_line_set_points(line, copy_ext->point_array, copy_ext->point_num);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("line created");
|
||||
@@ -122,41 +117,11 @@ void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t po
|
||||
ext->point_array = point_a;
|
||||
ext->point_num = point_num;
|
||||
|
||||
if(point_num > 0 && ext->auto_size != 0) {
|
||||
uint16_t i;
|
||||
lv_coord_t xmax = LV_COORD_MIN;
|
||||
lv_coord_t ymax = LV_COORD_MIN;
|
||||
for(i = 0; i < point_num; i++) {
|
||||
xmax = LV_MATH_MAX(point_a[i].x, xmax);
|
||||
ymax = LV_MATH_MAX(point_a[i].y, ymax);
|
||||
}
|
||||
|
||||
lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN);
|
||||
lv_obj_set_size(line, xmax + line_width, ymax + line_width);
|
||||
}
|
||||
_lv_obj_handle_self_size_chg(line);
|
||||
|
||||
lv_obj_invalidate(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable (or disable) the auto-size option. The size of the object will fit to its points.
|
||||
* (set width to x max and height to y max)
|
||||
* @param line pointer to a line object
|
||||
* @param en true: auto size is enabled, false: auto size is disabled
|
||||
*/
|
||||
void lv_line_set_auto_size(lv_obj_t * line, bool en)
|
||||
{
|
||||
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
|
||||
|
||||
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
|
||||
if(ext->auto_size == en) return;
|
||||
|
||||
ext->auto_size = en == false ? 0 : 1;
|
||||
|
||||
/*Refresh the object*/
|
||||
if(en) lv_line_set_points(line, ext->point_array, ext->point_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable (or disable) the y coordinate inversion.
|
||||
* If enabled then y will be subtracted from the height of the object,
|
||||
@@ -180,20 +145,6 @@ void lv_line_set_y_invert(lv_obj_t * line, bool en)
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the auto size attribute
|
||||
* @param line pointer to a line object
|
||||
* @return true: auto size is enabled, false: disabled
|
||||
*/
|
||||
bool lv_line_get_auto_size(const lv_obj_t * line)
|
||||
{
|
||||
LV_ASSERT_OBJ(line, LV_OBJX_NAME);
|
||||
|
||||
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
|
||||
|
||||
return ext->auto_size == 0 ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the y inversion attribute
|
||||
* @param line pointer to a line object
|
||||
@@ -234,8 +185,8 @@ static lv_design_res_t lv_line_design(lv_obj_t * line, const lv_area_t * clip_ar
|
||||
|
||||
lv_area_t area;
|
||||
lv_obj_get_coords(line, &area);
|
||||
lv_coord_t x_ofs = area.x1;
|
||||
lv_coord_t y_ofs = area.y1;
|
||||
lv_coord_t x_ofs = area.x1 - lv_obj_get_scroll_x(line);
|
||||
lv_coord_t y_ofs = area.y1 - lv_obj_get_scroll_y(line);
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t h = lv_obj_get_height(line);
|
||||
@@ -280,12 +231,34 @@ static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param)
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(line, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
/*The corner of the skew lines is out of the intended area*/
|
||||
lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN);
|
||||
if(line->ext_draw_pad < line_width) line->ext_draw_pad = line_width;
|
||||
lv_coord_t * s = param;
|
||||
if(*s < line_width) *s = line_width;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_SELF_SIZE) {
|
||||
lv_line_ext_t * ext = lv_obj_get_ext_attr(line);
|
||||
|
||||
lv_point_t * p = param;
|
||||
lv_coord_t w = 0;
|
||||
lv_coord_t h = 0;
|
||||
if(ext->point_num > 0) {
|
||||
uint16_t i;
|
||||
for(i = 0; i < ext->point_num; i++) {
|
||||
w = LV_MATH_MAX(ext->point_array[i].x, w);
|
||||
h = LV_MATH_MAX(ext->point_array[i].y, h);
|
||||
}
|
||||
|
||||
lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN);
|
||||
w += line_width;
|
||||
h += line_width;
|
||||
p->x = w;
|
||||
p->y = h;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@@ -32,7 +32,6 @@ typedef struct {
|
||||
/*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/
|
||||
const lv_point_t * point_array; /*Pointer to an array with the points of the line*/
|
||||
uint16_t point_num; /*Number of points in 'point_array' */
|
||||
uint8_t auto_size : 1; /*1: set obj. width to x max and obj. height to y max */
|
||||
uint8_t y_inv : 1; /*1: y == 0 will be on the bottom*/
|
||||
} lv_line_ext_t;
|
||||
|
||||
@@ -66,14 +65,6 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
*/
|
||||
void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num);
|
||||
|
||||
/**
|
||||
* Enable (or disable) the auto-size option. The size of the object will fit to its points.
|
||||
* (set width to x max and height to y max)
|
||||
* @param line pointer to a line object
|
||||
* @param en true: auto size is enabled, false: auto size is disabled
|
||||
*/
|
||||
void lv_line_set_auto_size(lv_obj_t * line, bool en);
|
||||
|
||||
/**
|
||||
* Enable (or disable) the y coordinate inversion.
|
||||
* If enabled then y will be subtracted from the height of the object,
|
||||
@@ -92,13 +83,6 @@ work */
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the auto size attribute
|
||||
* @param line pointer to a line object
|
||||
* @return true: auto size is enabled, false: disabled
|
||||
*/
|
||||
bool lv_line_get_auto_size(const lv_obj_t * line);
|
||||
|
||||
/**
|
||||
* Get the y inversion attribute
|
||||
* @param line pointer to a line object
|
||||
|
||||
@@ -97,7 +97,7 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->cur_value = copy_ext->cur_value;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(linemeter, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(linemeter, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("line meter created");
|
||||
@@ -616,15 +616,11 @@ static lv_res_t lv_linemeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void *
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(lmeter, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_refresh_ext_draw_pad(lmeter);
|
||||
lv_obj_invalidate(lmeter);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ typedef struct {
|
||||
enum {
|
||||
LV_LINEMETER_PART_MAIN,
|
||||
_LV_LINEMETER_PART_VIRTUAL_LAST,
|
||||
_LV_LINEMETER_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_linemeter_part_t;
|
||||
|
||||
|
||||
@@ -1,931 +0,0 @@
|
||||
/**
|
||||
* @file lv_list.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_list.h"
|
||||
#if LV_USE_LIST != 0
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_list"
|
||||
|
||||
#define LV_LIST_LAYOUT_DEF LV_LAYOUT_COLUMN_MID
|
||||
|
||||
#if LV_USE_ANIMATION == 0
|
||||
#undef LV_LIST_DEF_ANIM_TIME
|
||||
#define LV_LIST_DEF_ANIM_TIME 0
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part);
|
||||
static bool lv_list_is_list_btn(lv_obj_t * list_btn);
|
||||
static bool lv_list_is_list_img(lv_obj_t * list_btn);
|
||||
static bool lv_list_is_list_label(lv_obj_t * list_btn);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if LV_USE_IMG
|
||||
static lv_signal_cb_t img_signal;
|
||||
#endif
|
||||
static lv_signal_cb_t label_signal;
|
||||
static lv_signal_cb_t ancestor_page_signal;
|
||||
static lv_signal_cb_t ancestor_btn_signal;
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a list objects
|
||||
* @param par pointer to an object, it will be the parent of the new list
|
||||
* @param copy pointer to a list object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created list
|
||||
*/
|
||||
lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("list create started");
|
||||
|
||||
/*Create the ancestor basic object*/
|
||||
lv_obj_t * list = lv_page_create(par, copy);
|
||||
LV_ASSERT_MEM(list);
|
||||
if(list == NULL) return NULL;
|
||||
|
||||
if(ancestor_page_signal == NULL) ancestor_page_signal = lv_obj_get_signal_cb(list);
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_allocate_ext_attr(list, sizeof(lv_list_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
ext->last_sel_btn = NULL;
|
||||
#endif
|
||||
ext->act_sel_btn = NULL;
|
||||
|
||||
lv_obj_set_signal_cb(list, lv_list_signal);
|
||||
|
||||
/*Init the new list object*/
|
||||
if(copy == NULL) {
|
||||
lv_page_set_anim_time(list, LV_LIST_DEF_ANIM_TIME);
|
||||
lv_page_set_scrollable_fit2(list, LV_FIT_PARENT, LV_FIT_TIGHT);
|
||||
lv_obj_set_size(list, 2 * LV_DPI, 3 * LV_DPI);
|
||||
lv_page_set_scrl_layout(list, LV_LIST_LAYOUT_DEF);
|
||||
lv_list_set_scrollbar_mode(list, LV_SCROLLBAR_MODE_DRAG);
|
||||
|
||||
lv_theme_apply(list, LV_THEME_LIST);
|
||||
|
||||
}
|
||||
else {
|
||||
lv_obj_t * copy_btn = lv_list_get_next_btn(copy, NULL);
|
||||
while(copy_btn) {
|
||||
const void * img_src = NULL;
|
||||
#if LV_USE_IMG
|
||||
lv_obj_t * copy_img = lv_list_get_btn_img(copy_btn);
|
||||
if(copy_img) img_src = lv_img_get_src(copy_img);
|
||||
#endif
|
||||
lv_list_add_btn(list, img_src, lv_list_get_btn_text(copy_btn));
|
||||
copy_btn = lv_list_get_next_btn(copy, copy_btn);
|
||||
}
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(list, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("list created");
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all children of the scrl object, without deleting scrl child.
|
||||
* @param list pointer to an object
|
||||
*/
|
||||
void lv_list_clean(lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(list);
|
||||
lv_obj_clean(scrl);
|
||||
}
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
/**
|
||||
* Add a list element to the list
|
||||
* @param list pointer to list object
|
||||
* @param img_fn file name of an image before the text (NULL if unused)
|
||||
* @param txt text of the list element (NULL if unused)
|
||||
* @return pointer to the new list element which can be customized (a button)
|
||||
*/
|
||||
lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * txt)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_t * last_btn = lv_list_get_prev_btn(list, NULL);
|
||||
|
||||
/*The coordinates may changed due to autofit so revert them at the end*/
|
||||
lv_coord_t pos_x_ori = lv_obj_get_x(list);
|
||||
lv_coord_t pos_y_ori = lv_obj_get_y(list);
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(list);
|
||||
lv_obj_add_protect(scrl, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/*Create a list element with the image an the text*/
|
||||
lv_obj_t * btn;
|
||||
btn = lv_btn_create(list, NULL);
|
||||
|
||||
lv_obj_add_protect(btn, LV_PROTECT_CHILD_CHG);
|
||||
|
||||
/*Save the original signal function because it will be required in `lv_list_btn_signal`*/
|
||||
if(ancestor_btn_signal == NULL) ancestor_btn_signal = lv_obj_get_signal_cb(btn);
|
||||
|
||||
/*Set the default styles*/
|
||||
lv_theme_apply(btn, LV_THEME_LIST_BTN);
|
||||
|
||||
lv_page_glue_obj(btn, true);
|
||||
lv_btn_set_layout(btn, LV_LAYOUT_ROW_MID);
|
||||
|
||||
lv_layout_t list_layout = lv_list_get_layout(list);
|
||||
bool layout_ver = false;
|
||||
if(list_layout == LV_LAYOUT_COLUMN_MID || list_layout == LV_LAYOUT_COLUMN_LEFT ||
|
||||
list_layout == LV_LAYOUT_COLUMN_RIGHT) {
|
||||
layout_ver = true;
|
||||
}
|
||||
|
||||
if(layout_ver) {
|
||||
lv_btn_set_fit2(btn, LV_FIT_PARENT, LV_FIT_TIGHT);
|
||||
}
|
||||
else {
|
||||
lv_coord_t w = last_btn ? lv_obj_get_width(last_btn) : (LV_DPI * 3) / 2;
|
||||
lv_btn_set_fit2(btn, LV_FIT_NONE, LV_FIT_TIGHT);
|
||||
lv_obj_set_width(btn, w);
|
||||
}
|
||||
|
||||
|
||||
lv_obj_add_protect(btn, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_set_signal_cb(btn, lv_list_btn_signal);
|
||||
|
||||
|
||||
#if LV_USE_IMG != 0
|
||||
lv_obj_t * img = NULL;
|
||||
if(img_src) {
|
||||
img = lv_img_create(btn, NULL);
|
||||
lv_img_set_src(img, img_src);
|
||||
lv_obj_set_click(img, false);
|
||||
if(img_signal == NULL) img_signal = lv_obj_get_signal_cb(img);
|
||||
}
|
||||
#endif
|
||||
if(txt != NULL) {
|
||||
lv_obj_t * label = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(label, txt);
|
||||
lv_obj_set_click(label, false);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);
|
||||
if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL) {
|
||||
lv_coord_t pad = lv_obj_get_style_pad_left(btn, LV_BTN_PART_MAIN);
|
||||
lv_obj_set_width(label, label->coords.x2 - btn->coords.x1 - pad);
|
||||
}
|
||||
else {
|
||||
lv_coord_t pad = lv_obj_get_style_pad_right(btn, LV_BTN_PART_MAIN);
|
||||
lv_obj_set_width(label, btn->coords.x2 - label->coords.x1 - pad);
|
||||
}
|
||||
if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label);
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/* If this is the first item to be added to the list and the list is
|
||||
* focused, select it */
|
||||
{
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if(lv_list_get_next_btn(list, NULL) == btn && lv_group_get_focused(g) == list) {
|
||||
lv_list_focus_btn(list, btn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_clear_protect(scrl, LV_PROTECT_CHILD_CHG);
|
||||
lv_obj_clear_protect(btn, LV_PROTECT_CHILD_CHG);
|
||||
btn->signal_cb(btn, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
|
||||
lv_obj_set_pos(list, pos_x_ori, pos_y_ori);
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the index of the button in the list
|
||||
* @param list pointer to a list object
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index <
|
||||
* lv_list_ext_t.size
|
||||
* @return true: successfully deleted
|
||||
*/
|
||||
bool lv_list_remove(const lv_obj_t * list, uint16_t index)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
uint16_t count = 0;
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(count == index) {
|
||||
#if LV_USE_GROUP
|
||||
if(e == ext->last_sel_btn) ext->last_sel_btn = NULL;
|
||||
#endif
|
||||
if(e == ext->act_sel_btn) ext->act_sel_btn = NULL;
|
||||
|
||||
lv_obj_del(e);
|
||||
return true;
|
||||
}
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
count++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Make a button selected
|
||||
* @param list pointer to a list object
|
||||
* @param btn pointer to a button to select
|
||||
* NULL to not select any buttons
|
||||
*/
|
||||
void lv_list_focus_btn(lv_obj_t * list, lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
if(btn) {
|
||||
LV_ASSERT_OBJ(btn, "lv_btn");
|
||||
}
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
/*Defocus the current button*/
|
||||
if(ext->act_sel_btn) lv_obj_clear_state(ext->act_sel_btn, LV_STATE_FOCUSED);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/*Don't forget which button was selected.
|
||||
* It will be restored when the list is focused again.*/
|
||||
if(btn) ext->last_sel_btn = btn;
|
||||
#endif
|
||||
|
||||
/*Focus the new button*/
|
||||
ext->act_sel_btn = btn;
|
||||
|
||||
if(ext->act_sel_btn) {
|
||||
lv_obj_add_state(ext->act_sel_btn, LV_STATE_FOCUSED);
|
||||
lv_page_focus(list, ext->act_sel_btn, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set layout of a list
|
||||
* @param list pointer to a list object
|
||||
* @param layout which layout should be used
|
||||
*/
|
||||
void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
/* Update list layout if necessary */
|
||||
if(layout == lv_list_get_layout(list)) return;
|
||||
|
||||
/* Get the first button on the list */
|
||||
lv_obj_t * btn = lv_list_get_prev_btn(list, NULL);
|
||||
|
||||
/* Visit all buttons on the list and update their layout */
|
||||
while(btn != NULL) {
|
||||
/*If a column layout set the buttons' width to list width*/
|
||||
if(layout == LV_LAYOUT_COLUMN_MID || layout == LV_LAYOUT_COLUMN_LEFT || layout == LV_LAYOUT_COLUMN_RIGHT) {
|
||||
lv_btn_set_fit2(btn, LV_FIT_PARENT, LV_FIT_TIGHT);
|
||||
}
|
||||
/*If a row layout set the buttons' width according to the content*/
|
||||
else if(layout == LV_LAYOUT_ROW_MID || layout == LV_LAYOUT_ROW_TOP || layout == LV_LAYOUT_ROW_BOTTOM) {
|
||||
lv_btn_set_fit(btn, LV_FIT_TIGHT);
|
||||
}
|
||||
|
||||
btn = lv_list_get_prev_btn(list, btn);
|
||||
}
|
||||
|
||||
if(layout == LV_LAYOUT_COLUMN_MID || layout == LV_LAYOUT_COLUMN_LEFT || layout == LV_LAYOUT_COLUMN_RIGHT) {
|
||||
lv_page_set_scrollable_fit2(list, LV_FIT_PARENT, LV_FIT_TIGHT);
|
||||
}
|
||||
else if(layout == LV_LAYOUT_ROW_MID || layout == LV_LAYOUT_ROW_TOP || layout == LV_LAYOUT_ROW_BOTTOM) {
|
||||
lv_page_set_scrollable_fit2(list, LV_FIT_TIGHT, LV_FIT_TIGHT);
|
||||
lv_cont_set_fit2(list, LV_FIT_NONE, LV_FIT_TIGHT);
|
||||
}
|
||||
|
||||
lv_page_set_scrl_layout(list, layout);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the text of a list element
|
||||
* @param btn pointer to list element
|
||||
* @return pointer to the text
|
||||
*/
|
||||
const char * lv_list_get_btn_text(const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, "lv_btn");
|
||||
|
||||
lv_obj_t * label = lv_list_get_btn_label(btn);
|
||||
if(label == NULL) return "";
|
||||
return lv_label_get_text(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param btn 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_btn_label(const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, "lv_btn");
|
||||
|
||||
lv_obj_t * label = lv_obj_get_child_back(btn, NULL);
|
||||
if(label == NULL) return NULL;
|
||||
|
||||
while(lv_list_is_list_label(label) == false) {
|
||||
label = lv_obj_get_child_back(btn, label);
|
||||
if(label == NULL) break;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param btn 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_btn_img(const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, "lv_btn");
|
||||
|
||||
#if LV_USE_IMG != 0
|
||||
lv_obj_t * img = lv_obj_get_child_back(btn, NULL);
|
||||
if(img == NULL) return NULL;
|
||||
|
||||
while(lv_list_is_list_img(img) == false) {
|
||||
img = lv_obj_get_child_back(btn, img);
|
||||
if(img == NULL) break;
|
||||
}
|
||||
|
||||
return img;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the previous button from list. (Starts from the bottom button)
|
||||
* @param list pointer to a list object
|
||||
* @param prev_btn pointer to button. Search the previous before it.
|
||||
* @return pointer to the previous button or NULL when no more buttons
|
||||
*/
|
||||
lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
/* 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_scrollable(list);
|
||||
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
if(btn == NULL) return NULL;
|
||||
|
||||
while(lv_list_is_list_btn(btn) == false) {
|
||||
btn = lv_obj_get_child(scrl, btn);
|
||||
if(btn == NULL) break;
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next button from list. (Starts from the top button)
|
||||
* @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 when no more buttons
|
||||
*/
|
||||
lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
/* 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_scrollable(list);
|
||||
|
||||
btn = lv_obj_get_child_back(scrl, prev_btn);
|
||||
if(btn == NULL) return NULL;
|
||||
|
||||
while(lv_list_is_list_btn(btn) == false) {
|
||||
btn = lv_obj_get_child_back(scrl, btn);
|
||||
if(btn == NULL) break;
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the button in the list
|
||||
* @param list pointer to a list object. If NULL, assumes btn is part of a list.
|
||||
* @param btn pointer to a list element (button)
|
||||
* @return the index of the button in the list, or -1 of the button not in this list
|
||||
*/
|
||||
int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, "lv_btn");
|
||||
|
||||
int index = 0;
|
||||
if(list == NULL) {
|
||||
/* no list provided, assuming btn is part of a list */
|
||||
list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
}
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e == btn) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of buttons in the list
|
||||
* @param list pointer to a list object
|
||||
* @return the number of buttons in the list
|
||||
*/
|
||||
uint16_t lv_list_get_size(const lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
uint16_t size = 0;
|
||||
lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
|
||||
while(btn) {
|
||||
size++;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* Get the currently selected button
|
||||
* @param list pointer to a list object
|
||||
* @return pointer to the selected button
|
||||
*/
|
||||
lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
return ext->act_sel_btn;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get layout of a list
|
||||
* @param list pointer to a list object
|
||||
* @return layout of the list object
|
||||
*/
|
||||
lv_layout_t lv_list_get_layout(lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
return lv_page_get_scrl_layout(list);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Move the list elements up by one
|
||||
* @param list pointer a to list object
|
||||
*/
|
||||
void lv_list_up(const lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
/*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 * scrl = lv_page_get_scrollable(list);
|
||||
lv_obj_t * e;
|
||||
lv_obj_t * e_prev = NULL;
|
||||
|
||||
e = lv_list_get_prev_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->coords.y2 <= list->coords.y2) {
|
||||
if(e_prev != NULL) {
|
||||
lv_coord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
|
||||
if(lv_list_get_anim_time(list) == 0) {
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
}
|
||||
else {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, scrl);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
lv_anim_set_values(&a, lv_obj_get_y(scrl), new_y);
|
||||
lv_anim_set_time(&a, LV_LIST_DEF_ANIM_TIME);
|
||||
lv_anim_start(&a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
e_prev = e;
|
||||
e = lv_list_get_prev_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the list elements down by one
|
||||
* @param list pointer to a list object
|
||||
*/
|
||||
void lv_list_down(const lv_obj_t * list)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
/*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 * scrl = lv_page_get_scrollable(list);
|
||||
lv_obj_t * e;
|
||||
e = lv_list_get_prev_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->coords.y1 < list->coords.y1) {
|
||||
lv_coord_t new_y = -lv_obj_get_y(e);
|
||||
if(lv_list_get_anim_time(list) == 0) {
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
}
|
||||
else {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, scrl);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
lv_anim_set_values(&a, lv_obj_get_y(scrl), new_y);
|
||||
lv_anim_set_time(&a, LV_LIST_DEF_ANIM_TIME);
|
||||
lv_anim_start(&a);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
e = lv_list_get_prev_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus on a list button. It ensures that the button will be visible on the list.
|
||||
* @param btn pointer to a list button to focus
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation, LV_ANOM_OFF: without animation
|
||||
*/
|
||||
void lv_list_focus(const lv_obj_t * btn, lv_anim_enable_t anim)
|
||||
{
|
||||
LV_ASSERT_OBJ(btn, "");
|
||||
|
||||
#if LV_USE_ANIMATION == 0
|
||||
anim = false;
|
||||
#endif
|
||||
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
|
||||
lv_page_focus(list, btn, anim == LV_ANIM_OFF ? 0 : lv_list_get_anim_time(list));
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the list
|
||||
* @param list pointer to a list object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_list_get_style(list, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_page_signal(list, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_page_signal(list, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING ||
|
||||
sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
#if LV_USE_GROUP
|
||||
/*If pressed/released etc by a KEYPAD or ENCODER delegate signal and events to the button*/
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_KEYPAD ||
|
||||
(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list)))) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
/*The page receives the key presses so the events should be propagated to the selected
|
||||
* button*/
|
||||
if(ext->act_sel_btn) {
|
||||
res = lv_signal_send(ext->act_sel_btn, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_PRESSED) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_PRESSED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSING) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_PRESSING, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_LONG_PRESSED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(indev->proc.long_pr_sent == 0) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_SHORT_CLICKED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
if(lv_indev_is_dragging(indev) == false) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_CLICKED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_RELEASED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_FOCUS) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
/*With ENCODER focus the button only in edit mode*/
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if((indev_type == LV_INDEV_TYPE_KEYPAD) ||
|
||||
(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(g))) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/* Select the last used button, or use the first no last button */
|
||||
if(ext->last_sel_btn) lv_list_focus_btn(list, ext->last_sel_btn);
|
||||
else lv_list_focus_btn(list, lv_list_get_next_btn(list, NULL));
|
||||
}
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(g) == false) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
if(ext->act_sel_btn) lv_obj_clear_state(ext->act_sel_btn, LV_STATE_PRESSED);
|
||||
if(ext->last_sel_btn) lv_obj_clear_state(ext->last_sel_btn, LV_STATE_PRESSED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/*De-select the selected btn*/
|
||||
lv_list_focus_btn(list, NULL);
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
ext->act_sel_btn = NULL;
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
#if LV_USE_GROUP
|
||||
bool * editable = (bool *)param;
|
||||
*editable = true;
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
char c = *((char *)param);
|
||||
if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/*If there is a valid selected button the make the previous selected*/
|
||||
if(ext->act_sel_btn) {
|
||||
lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->act_sel_btn);
|
||||
if(btn_prev) lv_list_focus_btn(list, btn_prev);
|
||||
}
|
||||
/*If there is no selected button the make the first selected*/
|
||||
else {
|
||||
lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
|
||||
if(btn)
|
||||
lv_list_focus_btn(list,
|
||||
btn); /*If there are no buttons on the list then there is no first button*/
|
||||
}
|
||||
}
|
||||
else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/*If there is a valid selected button the make the next selected*/
|
||||
if(ext->act_sel_btn != NULL) {
|
||||
lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->act_sel_btn);
|
||||
if(btn_next) lv_list_focus_btn(list, btn_next);
|
||||
}
|
||||
/*If there is no selected button the make the first selected*/
|
||||
else {
|
||||
lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
|
||||
if(btn) lv_list_focus_btn(list, btn);
|
||||
}
|
||||
}
|
||||
else if(c == LV_KEY_ESC) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/* Handle ESC/Cancel event */
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_CANCEL, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the list buttons
|
||||
* @param btn pointer to a button on the list
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_btn_signal(btn, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
|
||||
|
||||
if((sign == LV_SIGNAL_COORD_CHG && (lv_obj_get_width(btn) != lv_area_get_width(param) ||
|
||||
lv_obj_get_height(btn) != lv_area_get_height(param))) ||
|
||||
sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_t * label = lv_list_get_btn_label(btn);
|
||||
if(label) {
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(label, LV_LABEL_PART_MAIN);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL) {
|
||||
lv_coord_t pad = lv_obj_get_style_pad_left(btn, LV_BTN_PART_MAIN);
|
||||
lv_obj_set_size(label, label->coords.x2 - btn->coords.x1 - pad, font_h);
|
||||
}
|
||||
else {
|
||||
lv_coord_t pad = lv_obj_get_style_pad_right(btn, LV_BTN_PART_MAIN);
|
||||
lv_obj_set_size(label, btn->coords.x2 - label->coords.x1 - pad + 1, font_h);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_indev_is_dragging(lv_indev_get_act()) == false) {
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_focus_btn(list, btn);
|
||||
#if LV_USE_GROUP
|
||||
if(lv_obj_get_group(list)) {
|
||||
lv_group_focus_obj(list);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
#if LV_USE_GROUP
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
lv_obj_t * sel = lv_list_get_btn_selected(list);
|
||||
if(sel == btn) lv_list_focus_btn(list, lv_list_get_next_btn(list, btn));
|
||||
if(ext->last_sel_btn == btn) ext->last_sel_btn = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style descriptor of a part of the object
|
||||
* @param list pointer the object
|
||||
* @param part the part from `lv_page_list_t`. (LV_LIST_PART_...)
|
||||
* @return pointer to the style descriptor of the specified part
|
||||
*/
|
||||
static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part)
|
||||
{
|
||||
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_LIST_PART_BG:
|
||||
style_dsc_p = &list->style_list;
|
||||
break;
|
||||
case LV_LIST_PART_SCROLLABLE:
|
||||
style_dsc_p = &ext->page.scrl->style_list;
|
||||
break;
|
||||
case LV_LIST_PART_SCROLLBAR:
|
||||
style_dsc_p = &ext->page.scrlbar.style;
|
||||
break;
|
||||
#if LV_USE_ANIMATION
|
||||
case LV_LIST_PART_EDGE_FLASH:
|
||||
style_dsc_p = &ext->page.edge_flash.style;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
}
|
||||
|
||||
return style_dsc_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is really a list button or another object.
|
||||
* @param list_btn List button
|
||||
*/
|
||||
static bool lv_list_is_list_btn(lv_obj_t * list_btn)
|
||||
{
|
||||
lv_obj_type_t type;
|
||||
|
||||
lv_obj_get_type(list_btn, &type);
|
||||
uint8_t cnt;
|
||||
for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {
|
||||
if(type.type[cnt] == NULL) break;
|
||||
if(!strcmp(type.type[cnt], "lv_btn")) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is really a list label or another object.
|
||||
* @param list_label List label
|
||||
*/
|
||||
static bool lv_list_is_list_label(lv_obj_t * list_label)
|
||||
{
|
||||
lv_obj_type_t type;
|
||||
|
||||
lv_obj_get_type(list_label, &type);
|
||||
uint8_t cnt;
|
||||
for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {
|
||||
if(type.type[cnt] == NULL) break;
|
||||
if(!strcmp(type.type[cnt], "lv_label")) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is really a list image or another object.
|
||||
* @param list_image List image
|
||||
*/
|
||||
static bool lv_list_is_list_img(lv_obj_t * list_img)
|
||||
{
|
||||
lv_obj_type_t type;
|
||||
|
||||
lv_obj_get_type(list_img, &type);
|
||||
uint8_t cnt;
|
||||
for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {
|
||||
if(type.type[cnt] == NULL) break;
|
||||
if(!strcmp(type.type[cnt], "lv_img")) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,311 +0,0 @@
|
||||
/**
|
||||
* @file lv_list.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LIST_H
|
||||
#define LV_LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_LIST != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_PAGE == 0
|
||||
#error "lv_list: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTN == 0
|
||||
#error "lv_list: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL == 0
|
||||
#error "lv_list: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_page.h"
|
||||
#include "lv_btn.h"
|
||||
#include "lv_label.h"
|
||||
#include "lv_img.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of list*/
|
||||
typedef struct {
|
||||
lv_page_ext_t page; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
|
||||
#if LV_USE_GROUP
|
||||
lv_obj_t * last_sel_btn; /* The last selected button. It will be reverted when the list is focused again */
|
||||
#endif
|
||||
lv_obj_t * act_sel_btn; /* The button is currently being selected*/
|
||||
} lv_list_ext_t;
|
||||
|
||||
/** List styles. */
|
||||
enum {
|
||||
LV_LIST_PART_BG = LV_PAGE_PART_BG, /**< List background style */
|
||||
LV_LIST_PART_SCROLLBAR = LV_PAGE_PART_SCROLLBAR, /**< List scrollbar style. */
|
||||
LV_LIST_PART_EDGE_FLASH = LV_PAGE_PART_EDGE_FLASH, /**< List edge flash style. */
|
||||
_LV_LIST_PART_VIRTUAL_LAST = _LV_PAGE_PART_VIRTUAL_LAST,
|
||||
LV_LIST_PART_SCROLLABLE = LV_PAGE_PART_SCROLLABLE, /**< List scrollable area style. */
|
||||
_LV_LIST_PART_REAL_LAST = _LV_PAGE_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_list_style_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a list objects
|
||||
* @param par pointer to an object, it will be the parent of the new list
|
||||
* @param copy pointer to a list object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created list
|
||||
*/
|
||||
lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/**
|
||||
* Delete all children of the scrl object, without deleting scrl child.
|
||||
* @param list pointer to an object
|
||||
*/
|
||||
void lv_list_clean(lv_obj_t * list);
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/**
|
||||
* Add a list element to the list
|
||||
* @param list pointer to list object
|
||||
* @param img_fn file name of an image before the text (NULL if unused)
|
||||
* @param txt text of the list element (NULL if unused)
|
||||
* @return pointer to the new list element which can be customized (a button)
|
||||
*/
|
||||
lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * txt);
|
||||
|
||||
/**
|
||||
* Remove the index of the button in the list
|
||||
* @param list pointer to a list object
|
||||
* @param index pointer to a the button's index in the list, index must be 0 <= index <
|
||||
* lv_list_ext_t.size
|
||||
* @return true: successfully deleted
|
||||
*/
|
||||
bool lv_list_remove(const lv_obj_t * list, uint16_t index);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Make a button selected
|
||||
* @param list pointer to a list object
|
||||
* @param btn pointer to a button to select
|
||||
* NULL to not select any buttons
|
||||
*/
|
||||
void lv_list_focus_btn(lv_obj_t * list, lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Set the scroll bar mode of a list
|
||||
* @param list pointer to a list object
|
||||
* @param sb_mode the new mode from 'lv_page_sb_mode_t' enum
|
||||
*/
|
||||
static inline void lv_list_set_scrollbar_mode(lv_obj_t * list, lv_scrollbar_mode_t mode)
|
||||
{
|
||||
lv_page_set_scrollbar_mode(list, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the scroll propagation feature. If enabled then the List will move its parent if there is
|
||||
* no more space to scroll.
|
||||
* @param list pointer to a List
|
||||
* @param en true or false to enable/disable scroll propagation
|
||||
*/
|
||||
static inline void lv_list_set_scroll_propagation(lv_obj_t * list, bool en)
|
||||
{
|
||||
lv_page_set_scroll_propagation(list, en);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the edge flash effect. (Show an arc when the an edge is reached)
|
||||
* @param list pointer to a List
|
||||
* @param en true or false to enable/disable end flash
|
||||
*/
|
||||
static inline void lv_list_set_edge_flash(lv_obj_t * list, bool en)
|
||||
{
|
||||
lv_page_set_edge_flash(list, en);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scroll animation duration on 'list_up()' 'list_down()' 'list_focus()'
|
||||
* @param list pointer to a list object
|
||||
* @param anim_time duration of animation [ms]
|
||||
*/
|
||||
static inline void lv_list_set_anim_time(lv_obj_t * list, uint16_t anim_time)
|
||||
{
|
||||
lv_page_set_anim_time(list, anim_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set layout of a list
|
||||
* @param list pointer to a list object
|
||||
* @param layout which layout should be used
|
||||
*/
|
||||
void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the text of a list element
|
||||
* @param btn pointer to list element
|
||||
* @return pointer to the text
|
||||
*/
|
||||
const char * lv_list_get_btn_text(const lv_obj_t * btn);
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param btn 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_btn_label(const lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param btn 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_btn_img(const lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the next button from list. (Starts from the bottom button)
|
||||
* @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 when no more buttons
|
||||
*/
|
||||
lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn);
|
||||
|
||||
/**
|
||||
* Get the previous button from list. (Starts from the top button)
|
||||
* @param list pointer to a list object
|
||||
* @param prev_btn pointer to button. Search the previous before it.
|
||||
* @return pointer to the previous button or NULL when no more buttons
|
||||
*/
|
||||
lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn);
|
||||
|
||||
/**
|
||||
* Get the index of the button in the list
|
||||
* @param list pointer to a list object. If NULL, assumes btn is part of a list.
|
||||
* @param btn pointer to a list element (button)
|
||||
* @return the index of the button in the list, or -1 of the button not in this list
|
||||
*/
|
||||
int32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the number of buttons in the list
|
||||
* @param list pointer to a list object
|
||||
* @return the number of buttons in the list
|
||||
*/
|
||||
uint16_t lv_list_get_size(const lv_obj_t * list);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* Get the currently selected button. Can be used while navigating in the list with a keypad.
|
||||
* @param list pointer to a list object
|
||||
* @return pointer to the selected button
|
||||
*/
|
||||
lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get layout of a list
|
||||
* @param list pointer to a list object
|
||||
* @return layout of the list object
|
||||
*/
|
||||
lv_layout_t lv_list_get_layout(lv_obj_t * list);
|
||||
|
||||
/**
|
||||
* Get the scroll bar mode of a list
|
||||
* @param list pointer to a list object
|
||||
* @return scrollbar mode from 'lv_scrollbar_mode_t' enum
|
||||
*/
|
||||
static inline lv_scrollbar_mode_t lv_list_get_scrollbar_mode(const lv_obj_t * list)
|
||||
{
|
||||
return lv_page_get_scrollbar_mode(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scroll propagation property
|
||||
* @param list pointer to a List
|
||||
* @return true or false
|
||||
*/
|
||||
static inline bool lv_list_get_scroll_propagation(lv_obj_t * list)
|
||||
{
|
||||
return lv_page_get_scroll_propagation(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scroll propagation property
|
||||
* @param list pointer to a List
|
||||
* @return true or false
|
||||
*/
|
||||
static inline bool lv_list_get_edge_flash(lv_obj_t * list)
|
||||
{
|
||||
return lv_page_get_edge_flash(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scroll animation duration
|
||||
* @param list pointer to a list object
|
||||
* @return duration of animation [ms]
|
||||
*/
|
||||
static inline uint16_t lv_list_get_anim_time(const lv_obj_t * list)
|
||||
{
|
||||
return lv_page_get_anim_time(list);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Move the list elements up by one
|
||||
* @param list pointer a to list object
|
||||
*/
|
||||
void lv_list_up(const lv_obj_t * list);
|
||||
/**
|
||||
* Move the list elements down by one
|
||||
* @param list pointer to a list object
|
||||
*/
|
||||
void lv_list_down(const lv_obj_t * list);
|
||||
|
||||
/**
|
||||
* Focus on a list button. It ensures that the button will be visible on the list.
|
||||
* @param btn pointer to a list button to focus
|
||||
* @param anim LV_ANOM_ON: scroll with animation, LV_ANIM_OFF: without animation
|
||||
*/
|
||||
void lv_list_focus(const lv_obj_t * btn, lv_anim_enable_t anim);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LIST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LIST_H*/
|
||||
@@ -1,638 +0,0 @@
|
||||
/**
|
||||
* @file lv_msgbox.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_msgbox.h"
|
||||
#if LV_USE_MSGBOX != 0
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "../lv_core/lv_disp.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_msgbox"
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
#ifndef LV_MSGBOX_CLOSE_ANIM_TIME
|
||||
#define LV_MSGBOX_CLOSE_ANIM_TIME 200 /*List close animation time) */
|
||||
#endif
|
||||
#else
|
||||
#undef LV_MSGBOX_CLOSE_ANIM_TIME
|
||||
#define LV_MSGBOX_CLOSE_ANIM_TIME 0 /*No animations*/
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_msgbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param);
|
||||
static void mbox_realign(lv_obj_t * mbox);
|
||||
static lv_style_list_t * lv_msgbox_get_style(lv_obj_t * mbox, uint8_t part);
|
||||
#if LV_USE_ANIMATION
|
||||
static void lv_msgbox_close_ready_cb(lv_anim_t * a);
|
||||
#endif
|
||||
static void lv_msgbox_default_event_cb(lv_obj_t * mbox, lv_event_t event);
|
||||
static void lv_msgbox_btnm_event_cb(lv_obj_t * btnm, lv_event_t event);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a message box objects
|
||||
* @param par pointer to an object, it will be the parent of the new message box
|
||||
* @param copy pointer to a message box object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created message box
|
||||
*/
|
||||
lv_obj_t * lv_msgbox_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("message box create started");
|
||||
|
||||
/*Create the ancestor message box*/
|
||||
lv_obj_t * mbox = lv_cont_create(par, copy);
|
||||
LV_ASSERT_MEM(mbox);
|
||||
if(mbox == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(mbox);
|
||||
|
||||
/*Allocate the message box type specific extended data*/
|
||||
lv_msgbox_ext_t * ext = lv_obj_allocate_ext_attr(mbox, sizeof(lv_msgbox_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(mbox);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext->text = NULL;
|
||||
ext->btnm = NULL;
|
||||
#if LV_USE_ANIMATION
|
||||
ext->anim_time = LV_MSGBOX_CLOSE_ANIM_TIME;
|
||||
#endif
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(mbox, lv_msgbox_signal);
|
||||
|
||||
/*Init the new message box message box*/
|
||||
if(copy == NULL) {
|
||||
ext->text = lv_label_create(mbox, NULL);
|
||||
lv_label_set_align(ext->text, LV_LABEL_ALIGN_CENTER);
|
||||
lv_label_set_long_mode(ext->text, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_text(ext->text, "Message");
|
||||
|
||||
lv_cont_set_layout(mbox, LV_LAYOUT_COLUMN_MID);
|
||||
lv_cont_set_fit2(mbox, LV_FIT_NONE, LV_FIT_TIGHT);
|
||||
lv_coord_t fit_w = lv_obj_get_width_fit(par);
|
||||
if(lv_disp_get_size_category(NULL) <= LV_DISP_SIZE_SMALL) {
|
||||
lv_obj_set_width(mbox, fit_w);
|
||||
}
|
||||
else {
|
||||
lv_obj_set_width(mbox, LV_MATH_MIN(fit_w, LV_DPX(400)));
|
||||
}
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_event_cb(mbox, lv_msgbox_default_event_cb);
|
||||
|
||||
/*Set the default styles*/
|
||||
lv_theme_apply(mbox, LV_THEME_MSGBOX);
|
||||
|
||||
}
|
||||
/*Copy an existing message box*/
|
||||
else {
|
||||
lv_msgbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
|
||||
ext->text = lv_label_create(mbox, copy_ext->text);
|
||||
|
||||
/*Copy the buttons and the label on them*/
|
||||
if(copy_ext->btnm) ext->btnm = lv_btnmatrix_create(mbox, copy_ext->btnm);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(mbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("message box created");
|
||||
|
||||
return mbox;
|
||||
}
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/**
|
||||
* Add button to the message box
|
||||
* @param mbox pointer to message box object
|
||||
* @param btn_map button descriptor (button matrix map).
|
||||
* E.g. a const char *txt[] = {"ok", "close", ""} (Can not be local variable)
|
||||
*/
|
||||
void lv_msgbox_add_btns(lv_obj_t * mbox, const char * btn_map[])
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
LV_ASSERT_NULL(btn_map);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
|
||||
/*Create a button matrix if not exists yet*/
|
||||
if(ext->btnm == NULL) {
|
||||
ext->btnm = lv_btnmatrix_create(mbox, NULL);
|
||||
|
||||
lv_theme_apply(mbox, LV_THEME_MSGBOX_BTNS);
|
||||
}
|
||||
|
||||
lv_btnmatrix_set_map(ext->btnm, btn_map);
|
||||
lv_btnmatrix_set_btn_ctrl_all(ext->btnm, LV_BTNMATRIX_CTRL_CLICK_TRIG | LV_BTNMATRIX_CTRL_NO_REPEAT);
|
||||
lv_obj_set_event_cb(ext->btnm, lv_msgbox_btnm_event_cb);
|
||||
|
||||
if(lv_obj_is_focused(mbox)) {
|
||||
lv_state_t state = lv_obj_get_state(mbox, LV_MSGBOX_PART_BG);
|
||||
if(state & LV_STATE_EDITED) {
|
||||
lv_obj_set_state(ext->btnm, LV_STATE_FOCUSED | LV_STATE_EDITED);
|
||||
}
|
||||
else {
|
||||
lv_obj_set_state(ext->btnm, LV_STATE_FOCUSED);
|
||||
}
|
||||
|
||||
lv_btnmatrix_set_focused_btn(ext->btnm, 0);
|
||||
}
|
||||
|
||||
mbox_realign(mbox);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the text of the message box
|
||||
* @param mbox pointer to a message box
|
||||
* @param txt a '\0' terminated character string which will be the message box text
|
||||
*/
|
||||
void lv_msgbox_set_text(lv_obj_t * mbox, const char * txt)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
LV_ASSERT_STR(txt);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
lv_label_set_text(ext->text, txt);
|
||||
|
||||
mbox_realign(mbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a formatted text for the message box
|
||||
* @param mbox pointer to a message box
|
||||
* @param fmt `printf`-like format
|
||||
*/
|
||||
void lv_msgbox_set_text_fmt(lv_obj_t * mbox, const char * fmt, ...)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
LV_ASSERT_STR(fmt);
|
||||
|
||||
lv_msgbox_ext_t * msgbox_ext = lv_obj_get_ext_attr(mbox);
|
||||
lv_label_ext_t * label_ext = lv_obj_get_ext_attr(msgbox_ext->text);
|
||||
|
||||
/*If text is NULL then refresh */
|
||||
if(fmt == NULL) {
|
||||
lv_label_refr_text(msgbox_ext->text);
|
||||
return;
|
||||
}
|
||||
|
||||
if(label_ext->text != NULL) {
|
||||
lv_mem_free(label_ext->text);
|
||||
label_ext->text = NULL;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
label_ext->text = _lv_txt_set_text_vfmt(fmt, args);
|
||||
va_end(args);
|
||||
lv_label_refr_text(msgbox_ext->text);
|
||||
mbox_realign(mbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set animation duration
|
||||
* @param mbox pointer to a message box object
|
||||
* @param anim_time animation length in milliseconds (0: no animation)
|
||||
*/
|
||||
void lv_msgbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
anim_time = 0;
|
||||
ext->anim_time = anim_time;
|
||||
#else
|
||||
(void)mbox;
|
||||
(void)anim_time;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically delete the message box after a given time
|
||||
* @param mbox pointer to a message box object
|
||||
* @param delay a time (in milliseconds) to wait before delete the message box
|
||||
*/
|
||||
void lv_msgbox_start_auto_close(lv_obj_t * mbox, uint16_t delay)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
if(lv_msgbox_get_anim_time(mbox) != 0) {
|
||||
/*Add shrinking animations*/
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, mbox);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_height);
|
||||
lv_anim_set_values(&a, lv_obj_get_height(mbox), 0);
|
||||
lv_anim_set_time(&a, lv_msgbox_get_anim_time(mbox));
|
||||
lv_anim_set_delay(&a, delay);
|
||||
lv_anim_start(&a);
|
||||
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_width);
|
||||
lv_anim_set_values(&a, lv_obj_get_width(mbox), 0);
|
||||
lv_anim_set_ready_cb(&a, lv_msgbox_close_ready_cb);
|
||||
lv_anim_start(&a);
|
||||
|
||||
/*Disable fit to let shrinking work*/
|
||||
lv_cont_set_fit(mbox, LV_FIT_NONE);
|
||||
}
|
||||
else {
|
||||
/*Create an animation to delete the mbox `delay` ms later*/
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, mbox);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)NULL);
|
||||
lv_anim_set_values(&a, 0, 1);
|
||||
lv_anim_set_ready_cb(&a, lv_msgbox_close_ready_cb);
|
||||
lv_anim_set_time(&a, lv_msgbox_get_anim_time(mbox));
|
||||
lv_anim_set_delay(&a, delay);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
#else
|
||||
(void)delay; /*Unused*/
|
||||
lv_obj_del(mbox);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the auto. closing of message box
|
||||
* @param mbox pointer to a message box object
|
||||
*/
|
||||
void lv_msgbox_stop_auto_close(lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(mbox, NULL);
|
||||
#else
|
||||
(void)mbox; /*Unused*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether recoloring is enabled
|
||||
* @param mbox pointer to message box object
|
||||
* @param en whether recoloring is enabled
|
||||
*/
|
||||
void lv_msgbox_set_recolor(lv_obj_t * mbox, bool en)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
|
||||
if(ext->btnm) lv_btnmatrix_set_recolor(ext->btnm, en);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the text of the message box
|
||||
* @param mbox pointer to a message box object
|
||||
* @return pointer to the text of the message box
|
||||
*/
|
||||
const char * lv_msgbox_get_text(const lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
|
||||
return lv_label_get_text(ext->text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the lastly "activated" button by the user (pressed, released etc)
|
||||
* Useful in the the `event_cb`.
|
||||
* @param mbox pointer to message box object
|
||||
* @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset)
|
||||
*/
|
||||
uint16_t lv_msgbox_get_active_btn(lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
if(ext->btnm == NULL) return LV_BTNMATRIX_BTN_NONE;
|
||||
|
||||
uint16_t id = lv_btnmatrix_get_active_btn(ext->btnm);
|
||||
if(id == LV_BTNMATRIX_BTN_NONE) {
|
||||
id = lv_btnmatrix_get_focused_btn(ext->btnm);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of the lastly "activated" button by the user (pressed, released etc)
|
||||
* Useful in the the `event_cb`.
|
||||
* @param mbox pointer to message box object
|
||||
* @return text of the last released button (NULL: if unset)
|
||||
*/
|
||||
const char * lv_msgbox_get_active_btn_text(lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
if(ext->btnm)
|
||||
return lv_btnmatrix_get_active_btn_text(ext->btnm);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the animation duration (close animation time)
|
||||
* @param mbox pointer to a message box object
|
||||
* @return animation length in milliseconds (0: no animation)
|
||||
*/
|
||||
uint16_t lv_msgbox_get_anim_time(const lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
return ext->anim_time;
|
||||
#else
|
||||
(void)mbox;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether recoloring is enabled
|
||||
* @param mbox pointer to a message box object
|
||||
* @return whether recoloring is enabled
|
||||
*/
|
||||
bool lv_msgbox_get_recolor(const lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
|
||||
if(!ext->btnm) return false;
|
||||
|
||||
return lv_btnmatrix_get_recolor(ext->btnm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message box button matrix
|
||||
* @param mbox pointer to a message box object
|
||||
* @return pointer to button matrix object
|
||||
* @remarks return value will be NULL unless `lv_msgbox_add_btns` has been already called
|
||||
*/
|
||||
lv_obj_t * lv_msgbox_get_btnmatrix(lv_obj_t * mbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
return ext->btnm;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the message box
|
||||
* @param mbox pointer to a message box object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_msgbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/*Translate LV_KEY_UP/DOWN to LV_KEY_LEFT/RIGHT */
|
||||
char c_trans = 0;
|
||||
if(sign == LV_SIGNAL_CONTROL) {
|
||||
c_trans = *((char *)param);
|
||||
if(c_trans == LV_KEY_DOWN) c_trans = LV_KEY_LEFT;
|
||||
if(c_trans == LV_KEY_UP) c_trans = LV_KEY_RIGHT;
|
||||
|
||||
param = &c_trans;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_msgbox_get_style(mbox, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(mbox, sign, param);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_STATE_DSC) {
|
||||
lv_get_state_info_t * info = param;
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
if(ext->btnm && info->part == LV_MSGBOX_PART_BTN_BG) {
|
||||
info->result = lv_obj_get_state(ext->btnm, LV_BTNMATRIX_PART_BG);
|
||||
}
|
||||
else if(ext->btnm && info->part == LV_MSGBOX_PART_BTN) {
|
||||
info->result = lv_obj_get_state(ext->btnm, LV_BTNMATRIX_PART_BTN);
|
||||
}
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(mbox, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
if(lv_obj_get_width(mbox) != lv_area_get_width(param)) {
|
||||
mbox_realign(mbox);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
mbox_realign(mbox);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(ext->btnm) {
|
||||
uint32_t btn_id = lv_btnmatrix_get_focused_btn(ext->btnm);
|
||||
if(btn_id != LV_BTNMATRIX_BTN_NONE) lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
|
||||
}
|
||||
}
|
||||
else if(
|
||||
#if LV_USE_GROUP
|
||||
sign == LV_SIGNAL_CONTROL || sign == LV_SIGNAL_GET_EDITABLE ||
|
||||
#endif
|
||||
sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS) {
|
||||
if(ext->btnm) {
|
||||
ext->btnm->signal_cb(ext->btnm, sign, param);
|
||||
}
|
||||
|
||||
/* The button matrix with ENCODER input supposes it's in a group but in this case it isn't
|
||||
* (Only the message box's container) So so some actions here instead*/
|
||||
#if LV_USE_GROUP
|
||||
if(sign == LV_SIGNAL_FOCUS) {
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
/*In navigation mode don't select any button but in edit mode select the fist*/
|
||||
if(lv_group_get_editing(lv_obj_get_group(mbox))) lv_btnmatrix_set_focused_btn(ext->btnm, 0);
|
||||
else lv_btnmatrix_set_focused_btn(ext->btnm, LV_BTNMATRIX_BTN_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if(ext->btnm && (sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS)) {
|
||||
lv_state_t state = lv_obj_get_state(mbox, LV_MSGBOX_PART_BG);
|
||||
if(state & LV_STATE_FOCUSED) {
|
||||
lv_obj_set_state(ext->btnm, LV_STATE_FOCUSED);
|
||||
}
|
||||
else {
|
||||
lv_obj_clear_state(ext->btnm, LV_STATE_FOCUSED);
|
||||
|
||||
}
|
||||
if(state & LV_STATE_EDITED) {
|
||||
lv_obj_set_state(ext->btnm, LV_STATE_EDITED);
|
||||
}
|
||||
else {
|
||||
lv_obj_clear_state(ext->btnm, LV_STATE_EDITED);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style descriptor of a part of the object
|
||||
* @param mbox pointer the object
|
||||
* @param part the part from `lv_msgbox_part_t`. (LV_MSGBOX_PART_...)
|
||||
* @return pointer to the style descriptor of the specified part
|
||||
*/
|
||||
static lv_style_list_t * lv_msgbox_get_style(lv_obj_t * mbox, uint8_t part)
|
||||
{
|
||||
LV_ASSERT_OBJ(mbox, LV_OBJX_NAME);
|
||||
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_MSGBOX_PART_BG:
|
||||
style_dsc_p = &mbox->style_list;
|
||||
break;
|
||||
case LV_MSGBOX_PART_BTN_BG:
|
||||
style_dsc_p = ext->btnm ? lv_obj_get_style_list(ext->btnm, LV_BTNMATRIX_PART_BG) : NULL;
|
||||
break;
|
||||
case LV_MSGBOX_PART_BTN:
|
||||
style_dsc_p = ext->btnm ? lv_obj_get_style_list(ext->btnm, LV_BTNMATRIX_PART_BTN) : NULL;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
}
|
||||
|
||||
return style_dsc_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the button holder to fit
|
||||
* @param mbox pointer to message box object
|
||||
*/
|
||||
static void mbox_realign(lv_obj_t * mbox)
|
||||
{
|
||||
lv_msgbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
|
||||
|
||||
lv_coord_t w = lv_obj_get_width_fit(mbox);
|
||||
|
||||
if(ext->text) {
|
||||
lv_obj_set_width(ext->text, w);
|
||||
}
|
||||
|
||||
if(ext->btnm) {
|
||||
lv_style_int_t bg_top = lv_obj_get_style_pad_top(mbox, LV_MSGBOX_PART_BTN_BG);
|
||||
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(mbox, LV_MSGBOX_PART_BTN_BG);
|
||||
lv_style_int_t bg_inner = lv_obj_get_style_pad_inner(mbox, LV_MSGBOX_PART_BTN_BG);
|
||||
lv_style_int_t btn_top = lv_obj_get_style_pad_top(mbox, LV_MSGBOX_PART_BTN);
|
||||
lv_style_int_t btn_bottom = lv_obj_get_style_pad_bottom(mbox, LV_MSGBOX_PART_BTN);
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(mbox, LV_MSGBOX_PART_BTN);
|
||||
|
||||
uint16_t btnm_lines = 1;
|
||||
const char ** btnm_map = lv_btnmatrix_get_map_array(ext->btnm);
|
||||
uint16_t i;
|
||||
for(i = 0; btnm_map[i][0] != '\0'; i++) {
|
||||
if(btnm_map[i][0] == '\n') btnm_lines++;
|
||||
}
|
||||
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_coord_t btn_h = font_h + btn_top + btn_bottom;
|
||||
lv_obj_set_size(ext->btnm, w, btn_h * btnm_lines + bg_inner * (btnm_lines - 1) + bg_top + bg_bottom);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void lv_msgbox_close_ready_cb(lv_anim_t * a)
|
||||
{
|
||||
lv_obj_del(a->var);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void lv_msgbox_default_event_cb(lv_obj_t * mbox, lv_event_t event)
|
||||
{
|
||||
if(event != LV_EVENT_VALUE_CHANGED) return;
|
||||
|
||||
uint32_t btn_id = lv_msgbox_get_active_btn(mbox);
|
||||
if(btn_id == LV_BTNMATRIX_BTN_NONE) return;
|
||||
|
||||
lv_msgbox_start_auto_close(mbox, 0);
|
||||
}
|
||||
|
||||
static void lv_msgbox_btnm_event_cb(lv_obj_t * btnm, lv_event_t event)
|
||||
{
|
||||
lv_obj_t * mbox = lv_obj_get_parent(btnm);
|
||||
|
||||
/*clang-format off*/
|
||||
if(event == LV_EVENT_PRESSED || event == LV_EVENT_PRESSING || event == LV_EVENT_PRESS_LOST ||
|
||||
event == LV_EVENT_RELEASED || event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_CLICKED ||
|
||||
event == LV_EVENT_LONG_PRESSED || event == LV_EVENT_LONG_PRESSED_REPEAT ||
|
||||
event == LV_EVENT_VALUE_CHANGED) {
|
||||
lv_event_send(mbox, event, lv_event_get_data());
|
||||
}
|
||||
/*clang-format on*/
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,195 +0,0 @@
|
||||
/**
|
||||
* @file lv_mbox.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_MSGBOX_H
|
||||
#define LV_MSGBOX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_MSGBOX != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_CONT == 0
|
||||
#error "lv_mbox: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_BTNMATRIX == 0
|
||||
#error "lv_mbox: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BTNMATRIX 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_LABEL == 0
|
||||
#error "lv_mbox: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_cont.h"
|
||||
#include "lv_btnmatrix.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Data of message box*/
|
||||
typedef struct {
|
||||
lv_cont_ext_t bg; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t * text; /*Text of the message box*/
|
||||
lv_obj_t * btnm; /*Button matrix for the buttons*/
|
||||
#if LV_USE_ANIMATION
|
||||
uint16_t anim_time; /*Duration of close animation [ms] (0: no animation)*/
|
||||
#endif
|
||||
} lv_msgbox_ext_t;
|
||||
|
||||
/** Message box styles. */
|
||||
enum {
|
||||
LV_MSGBOX_PART_BG = LV_CONT_PART_MAIN,
|
||||
|
||||
LV_MSGBOX_PART_BTN_BG = _LV_CONT_PART_REAL_LAST,
|
||||
LV_MSGBOX_PART_BTN,
|
||||
};
|
||||
typedef uint8_t lv_msgbox_style_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a message box objects
|
||||
* @param par pointer to an object, it will be the parent of the new message box
|
||||
* @param copy pointer to a message box object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created message box
|
||||
*/
|
||||
lv_obj_t * lv_msgbox_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/**
|
||||
* Add button to the message box
|
||||
* @param mbox pointer to message box object
|
||||
* @param btn_map button descriptor (button matrix map).
|
||||
* E.g. a const char *txt[] = {"ok", "close", ""} (Can not be local variable)
|
||||
*/
|
||||
void lv_msgbox_add_btns(lv_obj_t * mbox, const char * btn_mapaction[]);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the text of the message box
|
||||
* @param mbox pointer to a message box
|
||||
* @param txt a '\0' terminated character string which will be the message box text
|
||||
*/
|
||||
void lv_msgbox_set_text(lv_obj_t * mbox, const char * txt);
|
||||
|
||||
/**
|
||||
* Set a formatted text for the message box
|
||||
* @param mbox pointer to a message box
|
||||
* @param fmt `printf`-like format
|
||||
*/
|
||||
void lv_msgbox_set_text_fmt(lv_obj_t * mbox, const char * fmt, ...);
|
||||
|
||||
/**
|
||||
* Set animation duration
|
||||
* @param mbox pointer to a message box object
|
||||
* @param anim_time animation length in milliseconds (0: no animation)
|
||||
*/
|
||||
void lv_msgbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time);
|
||||
|
||||
/**
|
||||
* Automatically delete the message box after a given time
|
||||
* @param mbox pointer to a message box object
|
||||
* @param delay a time (in milliseconds) to wait before delete the message box
|
||||
*/
|
||||
void lv_msgbox_start_auto_close(lv_obj_t * mbox, uint16_t delay);
|
||||
|
||||
/**
|
||||
* Stop the auto. closing of message box
|
||||
* @param mbox pointer to a message box object
|
||||
*/
|
||||
void lv_msgbox_stop_auto_close(lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Set whether recoloring is enabled. Must be called after `lv_msgbox_add_btns`.
|
||||
* @param mbox pointer to message box object
|
||||
* @param en whether recoloring is enabled
|
||||
*/
|
||||
void lv_msgbox_set_recolor(lv_obj_t * mbox, bool en);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the text of the message box
|
||||
* @param mbox pointer to a message box object
|
||||
* @return pointer to the text of the message box
|
||||
*/
|
||||
const char * lv_msgbox_get_text(const lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Get the index of the lastly "activated" button by the user (pressed, released etc)
|
||||
* Useful in the the `event_cb`.
|
||||
* @param mbox pointer to message box object
|
||||
* @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset)
|
||||
*/
|
||||
uint16_t lv_msgbox_get_active_btn(lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Get the text of the lastly "activated" button by the user (pressed, released etc)
|
||||
* Useful in the the `event_cb`.
|
||||
* @param mbox pointer to message box object
|
||||
* @return text of the last released button (NULL: if unset)
|
||||
*/
|
||||
const char * lv_msgbox_get_active_btn_text(lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Get the animation duration (close animation time)
|
||||
* @param mbox pointer to a message box object
|
||||
* @return animation length in milliseconds (0: no animation)
|
||||
*/
|
||||
uint16_t lv_msgbox_get_anim_time(const lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Get whether recoloring is enabled
|
||||
* @param mbox pointer to a message box object
|
||||
* @return whether recoloring is enabled
|
||||
*/
|
||||
bool lv_msgbox_get_recolor(const lv_obj_t * mbox);
|
||||
|
||||
/**
|
||||
* Get message box button matrix
|
||||
* @param mbox pointer to a message box object
|
||||
* @return pointer to button matrix object
|
||||
* @remarks return value will be NULL unless `lv_msgbox_add_btns` has been already called
|
||||
*/
|
||||
lv_obj_t * lv_msgbox_get_btnmatrix(lv_obj_t * mbox);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_MSGBOX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_MSGBOX_H*/
|
||||
@@ -54,7 +54,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
LV_LOG_TRACE("object mask create started");
|
||||
|
||||
/*Create the ancestor of object mask*/
|
||||
lv_obj_t * objmask = lv_cont_create(par, copy);
|
||||
lv_obj_t * objmask = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(objmask);
|
||||
if(objmask == NULL) return NULL;
|
||||
|
||||
@@ -86,7 +86,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
/* lv_objmask_ext_t * copy_ext = lv_obj_get_ext_attr(copy); */
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(objmask, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(objmask, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("object mask created");
|
||||
@@ -161,7 +161,7 @@ void lv_objmask_remove_mask(lv_obj_t * objmask, lv_objmask_mask_t * mask)
|
||||
/*Remove all masks*/
|
||||
if(mask == NULL) {
|
||||
lv_objmask_mask_t * m;
|
||||
_LV_LL_READ(ext->mask_ll, m) {
|
||||
_LV_LL_READ(&ext->mask_ll, m) {
|
||||
lv_mem_free(m->param);
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ static lv_design_res_t lv_objmask_design(lv_obj_t * objmask, const lv_area_t * c
|
||||
|
||||
lv_objmask_mask_t * m;
|
||||
|
||||
_LV_LL_READ(ext->mask_ll, m) {
|
||||
_LV_LL_READ(&ext->mask_ll, m) {
|
||||
lv_draw_mask_common_dsc_t * dsc = m->param;
|
||||
|
||||
if(dsc->type == LV_DRAW_MASK_TYPE_LINE) {
|
||||
@@ -293,11 +293,9 @@ static lv_design_res_t lv_objmask_design(lv_obj_t * objmask, const lv_area_t * c
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
lv_objmask_ext_t * ext = lv_obj_get_ext_attr(objmask);
|
||||
|
||||
|
||||
lv_objmask_mask_t * m;
|
||||
|
||||
_LV_LL_READ(ext->mask_ll, m) {
|
||||
_LV_LL_READ(&ext->mask_ll, m) {
|
||||
void * param;
|
||||
param = lv_draw_mask_remove_custom(m->param);
|
||||
_lv_mem_buf_release(param);
|
||||
@@ -322,12 +320,12 @@ static lv_res_t lv_objmask_signal(lv_obj_t * objmask, lv_signal_t sign, void * p
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(objmask, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_objmask_ext_t * ext = lv_obj_get_ext_attr(objmask);
|
||||
lv_objmask_mask_t * i;
|
||||
_LV_LL_READ(ext->mask_ll, i) {
|
||||
_LV_LL_READ(&ext->mask_ll, i) {
|
||||
if(i->param) {
|
||||
lv_mem_free(i->param);
|
||||
i->param = NULL;
|
||||
|
||||
@@ -18,7 +18,6 @@ extern "C" {
|
||||
#if LV_USE_OBJMASK != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_widgets/lv_cont.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -34,7 +33,6 @@ typedef struct {
|
||||
|
||||
/*Data of object mask*/
|
||||
typedef struct {
|
||||
lv_cont_ext_t cont; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_ll_t mask_ll; /*Store the created masks*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,426 +0,0 @@
|
||||
/**
|
||||
* @file lv_page.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_PAGE_H
|
||||
#define LV_PAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PAGE != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_CONT == 0
|
||||
#error "lv_page: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT 1) "
|
||||
#endif
|
||||
|
||||
#include "lv_cont.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Scrollbar modes: shows when should the scrollbars be visible*/
|
||||
enum {
|
||||
LV_SCROLLBAR_MODE_OFF = 0x0, /**< Never show scroll bars*/
|
||||
LV_SCROLLBAR_MODE_ON = 0x1, /**< Always show scroll bars*/
|
||||
LV_SCROLLBAR_MODE_DRAG = 0x2, /**< Show scroll bars when page is being dragged*/
|
||||
LV_SCROLLBAR_MODE_AUTO = 0x3, /**< Show scroll bars when the scrollable container is large enough to be scrolled*/
|
||||
LV_SCROLLBAR_MODE_HIDE = 0x4, /**< Hide the scroll bar temporally*/
|
||||
LV_SCROLLBAR_MODE_UNHIDE = 0x8, /**< Unhide the previously hidden scroll bar. Recover original mode too*/
|
||||
};
|
||||
typedef uint8_t lv_scrollbar_mode_t;
|
||||
|
||||
/** Edges: describes the four edges of the page*/
|
||||
enum { LV_PAGE_EDGE_LEFT = 0x1, LV_PAGE_EDGE_TOP = 0x2, LV_PAGE_EDGE_RIGHT = 0x4, LV_PAGE_EDGE_BOTTOM = 0x8 };
|
||||
typedef uint8_t lv_page_edge_t;
|
||||
|
||||
/*Data of page*/
|
||||
typedef struct {
|
||||
lv_cont_ext_t bg; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_obj_t * scrl; /*The scrollable object on the background*/
|
||||
struct {
|
||||
lv_style_list_t style; /*Style of scrollbars*/
|
||||
lv_area_t hor_area; /*Horizontal scrollbar area relative to the page. (Handled by the library) */
|
||||
lv_area_t ver_area; /*Vertical scrollbar area relative to the page (Handled by the library)*/
|
||||
uint8_t hor_draw : 1; /*1: horizontal scrollbar is visible now (Handled by the library)*/
|
||||
uint8_t ver_draw : 1; /*1: vertical scrollbar is visible now (Handled by the library)*/
|
||||
lv_scrollbar_mode_t mode : 3; /*Scrollbar visibility from 'lv_scrollbar_mode_t'*/
|
||||
} scrlbar;
|
||||
#if LV_USE_ANIMATION
|
||||
struct {
|
||||
lv_anim_value_t state; /*Store the current size of the edge flash effect*/
|
||||
lv_style_list_t style; /*Style of edge flash effect (usually homogeneous circle)*/
|
||||
uint8_t enabled : 1; /*1: Show a flash animation on the edge*/
|
||||
uint8_t top_ip : 1; /*Used internally to show that top most position is reached (flash is In
|
||||
Progress)*/
|
||||
uint8_t bottom_ip : 1; /*Used internally to show that bottom most position is reached (flash
|
||||
is In Progress)*/
|
||||
uint8_t right_ip : 1; /*Used internally to show that right most position is reached (flash
|
||||
is In Progress)*/
|
||||
uint8_t left_ip : 1; /*Used internally to show that left most position is reached (flash is
|
||||
In Progress)*/
|
||||
} edge_flash;
|
||||
|
||||
uint16_t anim_time; /*Scroll animation time*/
|
||||
#endif
|
||||
lv_obj_t * scroll_prop_obj; /*Pointer to child page from where the scroll is being propagated */
|
||||
uint8_t scroll_prop : 1; /*The direction of the scroll propagation*/
|
||||
} lv_page_ext_t;
|
||||
|
||||
enum {
|
||||
LV_PAGE_PART_BG = LV_CONT_PART_MAIN,
|
||||
LV_PAGE_PART_SCROLLBAR = _LV_OBJ_PART_VIRTUAL_LAST,
|
||||
LV_PAGE_PART_EDGE_FLASH,
|
||||
_LV_PAGE_PART_VIRTUAL_LAST,
|
||||
|
||||
LV_PAGE_PART_SCROLLABLE = _LV_OBJ_PART_REAL_LAST,
|
||||
_LV_PAGE_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_part_style_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a page objects
|
||||
* @param par pointer to an object, it will be the parent of the new page
|
||||
* @param copy pointer to a page object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created page
|
||||
*/
|
||||
lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/**
|
||||
* Delete all children of the scrl object, without deleting scrl child.
|
||||
* @param page pointer to an object
|
||||
*/
|
||||
void lv_page_clean(lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get the scrollable object of a page
|
||||
* @param page pointer to a page object
|
||||
* @return pointer to a container which is the scrollable part of the page
|
||||
*/
|
||||
lv_obj_t * lv_page_get_scrollable(const lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get the animation time
|
||||
* @param page pointer to a page object
|
||||
* @return the animation time in milliseconds
|
||||
*/
|
||||
uint16_t lv_page_get_anim_time(const lv_obj_t * page);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the scroll bar mode on a page
|
||||
* @param page pointer to a page object
|
||||
* @param sb_mode the new mode from 'lv_page_sb.mode_t' enum
|
||||
*/
|
||||
void lv_page_set_scrollbar_mode(lv_obj_t * page, lv_scrollbar_mode_t sb_mode);
|
||||
|
||||
/**
|
||||
* Set the animation time for the page
|
||||
* @param page pointer to a page object
|
||||
* @param anim_time animation time in milliseconds
|
||||
*/
|
||||
void lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time);
|
||||
|
||||
/**
|
||||
* Enable the scroll propagation feature. If enabled then the page will move its parent if there is
|
||||
* no more space to scroll.
|
||||
* The page needs to have a page-like parent (e.g. `lv_page`, `lv_tabview` tab, `lv_win` content area etc)
|
||||
* If enabled drag direction will be changed `LV_DRAG_DIR_ONE` automatically to allow scrolling only in one direction at one time.
|
||||
* @param page pointer to a Page
|
||||
* @param en true or false to enable/disable scroll propagation
|
||||
*/
|
||||
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en);
|
||||
|
||||
/**
|
||||
* Enable the edge flash effect. (Show an arc when the an edge is reached)
|
||||
* @param page pointer to a Page
|
||||
* @param en true or false to enable/disable end flash
|
||||
*/
|
||||
void lv_page_set_edge_flash(lv_obj_t * page, bool en);
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 directions separately.
|
||||
* It tell how to change the page size automatically.
|
||||
* @param page pointer to a page object
|
||||
* @param left left fit policy from `lv_fit_t`
|
||||
* @param right right fit policy from `lv_fit_t`
|
||||
* @param top bottom fit policy from `lv_fit_t`
|
||||
* @param bottom bottom fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_page_set_scrollable_fit4(lv_obj_t * page, lv_fit_t left, lv_fit_t right, lv_fit_t top,
|
||||
lv_fit_t bottom)
|
||||
{
|
||||
lv_cont_set_fit4(lv_page_get_scrollable(page), left, right, top, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy horizontally and vertically separately.
|
||||
* It tell how to change the page size automatically.
|
||||
* @param page pointer to a page object
|
||||
* @param hot horizontal fit policy from `lv_fit_t`
|
||||
* @param ver vertical fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_page_set_scrollable_fit2(lv_obj_t * page, lv_fit_t hor, lv_fit_t ver)
|
||||
{
|
||||
lv_cont_set_fit2(lv_page_get_scrollable(page), hor, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fit policy in all 4 direction at once.
|
||||
* It tell how to change the page size automatically.
|
||||
* @param page pointer to a button object
|
||||
* @param fit fit policy from `lv_fit_t`
|
||||
*/
|
||||
static inline void lv_page_set_scrollable_fit(lv_obj_t * page, lv_fit_t fit)
|
||||
{
|
||||
lv_cont_set_fit(lv_page_get_scrollable(page), fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set width of the scrollable part of a page
|
||||
* @param page pointer to a page object
|
||||
* @param w the new width of the scrollable (it ha no effect is horizontal fit is enabled)
|
||||
*/
|
||||
static inline void lv_page_set_scrl_width(lv_obj_t * page, lv_coord_t w)
|
||||
{
|
||||
lv_obj_set_width(lv_page_get_scrollable(page), w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set height of the scrollable part of a page
|
||||
* @param page pointer to a page object
|
||||
* @param h the new height of the scrollable (it ha no effect is vertical fit is enabled)
|
||||
*/
|
||||
static inline void lv_page_set_scrl_height(lv_obj_t * page, lv_coord_t h)
|
||||
{
|
||||
lv_obj_set_height(lv_page_get_scrollable(page), h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the layout of the scrollable part of the page
|
||||
* @param page pointer to a page object
|
||||
* @param layout a layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
static inline void lv_page_set_scrl_layout(lv_obj_t * page, lv_layout_t layout)
|
||||
{
|
||||
lv_cont_set_layout(lv_page_get_scrollable(page), layout);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the scroll bar mode on a page
|
||||
* @param page pointer to a page object
|
||||
* @return the mode from 'lv_page_sb.mode_t' enum
|
||||
*/
|
||||
lv_scrollbar_mode_t lv_page_get_scrollbar_mode(const lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get the scroll propagation property
|
||||
* @param page pointer to a Page
|
||||
* @return true or false
|
||||
*/
|
||||
bool lv_page_get_scroll_propagation(lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get the edge flash effect property.
|
||||
* @param page pointer to a Page
|
||||
* return true or false
|
||||
*/
|
||||
bool lv_page_get_edge_flash(lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get that width which can be set to the children to still not cause overflow (show scrollbars)
|
||||
* @param page pointer to a page object
|
||||
* @return the width which still fits into the page
|
||||
*/
|
||||
lv_coord_t lv_page_get_width_fit(lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Get that height which can be set to the children to still not cause overflow (show scrollbars)
|
||||
* @param page pointer to a page object
|
||||
* @return the height which still fits into the page
|
||||
*/
|
||||
lv_coord_t lv_page_get_height_fit(lv_obj_t * page);
|
||||
|
||||
/**
|
||||
* Divide the width of the object and get the width of a given number of columns.
|
||||
* Take into account the paddings of the background and scrollable too.
|
||||
* @param page pointer to an object
|
||||
* @param div indicates how many columns are assumed.
|
||||
* If 1 the width will be set the the parent's width
|
||||
* If 2 only half parent width - inner padding of the parent
|
||||
* If 3 only third parent width - 2 * inner padding of the parent
|
||||
* @param span how many columns are combined
|
||||
* @return the width according to the given parameters
|
||||
*/
|
||||
lv_coord_t lv_page_get_width_grid(lv_obj_t * page, uint8_t div, uint8_t span);
|
||||
|
||||
/**
|
||||
* Divide the height of the object and get the width of a given number of columns.
|
||||
* Take into account the paddings of the background and scrollable too.
|
||||
* @param page pointer to an object
|
||||
* @param div indicates how many rows are assumed.
|
||||
* If 1 the height will be set the the parent's height
|
||||
* If 2 only half parent height - inner padding of the parent
|
||||
* If 3 only third parent height - 2 * inner padding of the parent
|
||||
* @param span how many rows are combined
|
||||
* @return the height according to the given parameters
|
||||
*/
|
||||
lv_coord_t lv_page_get_height_grid(lv_obj_t * page, uint8_t div, uint8_t span);
|
||||
|
||||
/**
|
||||
* Get width of the scrollable part of a page
|
||||
* @param page pointer to a page object
|
||||
* @return the width of the scrollable
|
||||
*/
|
||||
static inline lv_coord_t lv_page_get_scrl_width(const lv_obj_t * page)
|
||||
{
|
||||
return lv_obj_get_width(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get height of the scrollable part of a page
|
||||
* @param page pointer to a page object
|
||||
* @return the height of the scrollable
|
||||
*/
|
||||
static inline lv_coord_t lv_page_get_scrl_height(const lv_obj_t * page)
|
||||
{
|
||||
return lv_obj_get_height(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout of the scrollable part of a page
|
||||
* @param page pointer to page object
|
||||
* @return the layout from 'lv_cont_layout_t'
|
||||
*/
|
||||
static inline lv_layout_t lv_page_get_scrl_layout(const lv_obj_t * page)
|
||||
{
|
||||
return lv_cont_get_layout(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left fit mode
|
||||
* @param page pointer to a page object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_page_get_scrl_fit_left(const lv_obj_t * page)
|
||||
{
|
||||
return lv_cont_get_fit_left(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right fit mode
|
||||
* @param page pointer to a page object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_page_get_scrl_fit_right(const lv_obj_t * page)
|
||||
{
|
||||
return lv_cont_get_fit_right(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top fit mode
|
||||
* @param page pointer to a page object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_page_get_scrl_fit_top(const lv_obj_t * page)
|
||||
{
|
||||
return lv_cont_get_fit_top(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bottom fit mode
|
||||
* @param page pointer to a page object
|
||||
* @return an element of `lv_fit_t`
|
||||
*/
|
||||
static inline lv_fit_t lv_page_get_scrl_fit_bottom(const lv_obj_t * page)
|
||||
{
|
||||
return lv_cont_get_fit_bottom(lv_page_get_scrollable(page));
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Find whether the page has been scrolled to a certain edge.
|
||||
* @param page Page object
|
||||
* @param edge Edge to check
|
||||
* @return true if the page is on the specified edge
|
||||
*/
|
||||
bool lv_page_on_edge(lv_obj_t * page, lv_page_edge_t edge);
|
||||
|
||||
/**
|
||||
* Glue the object to the page. After it the page can be moved (dragged) with this object too.
|
||||
* @param obj pointer to an object on a page
|
||||
* @param glue true: enable glue, false: disable glue
|
||||
*/
|
||||
void lv_page_glue_obj(lv_obj_t * obj, bool glue);
|
||||
|
||||
/**
|
||||
* Focus on an object. It ensures that the object will be visible on the page.
|
||||
* @param page pointer to a page object
|
||||
* @param obj pointer to an object to focus (must be on the page)
|
||||
* @param anim_en LV_ANIM_ON to focus with animation; LV_ANIM_OFF to focus without animation
|
||||
*/
|
||||
void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll the page horizontally
|
||||
* @param page pointer to a page object
|
||||
* @param dist the distance to scroll (< 0: scroll left; > 0 scroll right)
|
||||
*/
|
||||
void lv_page_scroll_hor(lv_obj_t * page, lv_coord_t dist);
|
||||
|
||||
/**
|
||||
* Scroll the page vertically
|
||||
* @param page pointer to a page object
|
||||
* @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)
|
||||
*/
|
||||
void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist);
|
||||
|
||||
/**
|
||||
* Not intended to use directly by the user but by other object types internally.
|
||||
* Start an edge flash animation.
|
||||
* @param page
|
||||
* @param edge the edge to flash. Can be `LV_PAGE_EDGE_LEFT/RIGHT/TOP/BOTTOM`
|
||||
*/
|
||||
void lv_page_start_edge_flash(lv_obj_t * page, lv_page_edge_t edge);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_PAGE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PAGE_H*/
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
#include "../lv_core/lv_indev_scroll.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
|
||||
/*********************
|
||||
@@ -33,26 +35,25 @@
|
||||
**********************/
|
||||
static lv_design_res_t lv_roller_design(lv_obj_t * roller, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_design_res_t lv_roller_label_design(lv_obj_t * label, const lv_area_t * clip_area, lv_design_mode_t mode);
|
||||
static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_roller_get_style(lv_obj_t * roller, uint8_t part);
|
||||
static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param);
|
||||
static lv_res_t lv_roller_label_signal(lv_obj_t * label, lv_signal_t sign, void * param);
|
||||
static void refr_position(lv_obj_t * roller, lv_anim_enable_t animen);
|
||||
static void refr_height(lv_obj_t * roller);
|
||||
static void refr_width(lv_obj_t * roller);
|
||||
static lv_res_t release_handler(lv_obj_t * roller);
|
||||
static void inf_normalize(void * roller_scrl);
|
||||
static void inf_normalize(lv_obj_t * roller_scrl);
|
||||
static lv_obj_t * get_label(const lv_obj_t * roller);
|
||||
static lv_coord_t get_selected_label_width(const lv_obj_t * roller);
|
||||
#if LV_USE_ANIMATION
|
||||
static void scroll_anim_ready_cb(lv_anim_t * a);
|
||||
#endif
|
||||
static void draw_bg(lv_obj_t * roller, const lv_area_t * clip_area);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_label_signal;
|
||||
static lv_design_cb_t ancestor_label_design;
|
||||
static lv_signal_cb_t ancestor_scrl_signal;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -73,12 +74,12 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
LV_LOG_TRACE("roller create started");
|
||||
|
||||
/*Create the ancestor of roller*/
|
||||
lv_obj_t * roller = lv_page_create(par, copy);
|
||||
lv_obj_t * roller = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(roller);
|
||||
if(roller == NULL) return NULL;
|
||||
|
||||
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrollable(roller));
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(roller);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(roller);
|
||||
|
||||
/*Allocate the roller type specific extended data*/
|
||||
lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(roller, sizeof(lv_roller_ext_t));
|
||||
@@ -92,49 +93,51 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->option_cnt = 0;
|
||||
ext->sel_opt_id = 0;
|
||||
ext->sel_opt_id_ori = 0;
|
||||
ext->auto_fit = 1;
|
||||
lv_style_list_init(&ext->style_sel);
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(roller, lv_roller_signal);
|
||||
lv_obj_set_design_cb(roller, lv_roller_design);
|
||||
|
||||
/*Init the new roller roller*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_clear_flag(roller, LV_OBJ_FLAG_SCROLLABLE);
|
||||
ext->anim_time = LV_ROLLER_DEF_ANIM_TIME;
|
||||
lv_obj_set_width(roller, LV_SIZE_AUTO);
|
||||
|
||||
lv_obj_t * label = lv_label_create(roller, NULL);
|
||||
lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
|
||||
|
||||
if(ancestor_label_design == NULL) ancestor_label_design = lv_obj_get_design_cb(label);
|
||||
if(ancestor_label_signal == NULL) ancestor_label_signal = lv_obj_get_signal_cb(label);
|
||||
lv_obj_set_design_cb(label, lv_roller_label_design);
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(roller);
|
||||
lv_obj_set_drag(scrl, true);
|
||||
lv_page_set_scrollable_fit2(roller, LV_FIT_PARENT, LV_FIT_NONE); /*Height is specified directly*/
|
||||
lv_roller_set_anim_time(roller, LV_ROLLER_DEF_ANIM_TIME);
|
||||
lv_obj_set_signal_cb(label, lv_roller_label_signal);
|
||||
|
||||
lv_obj_set_signal_cb(roller, lv_roller_signal);
|
||||
lv_obj_set_design_cb(roller, lv_roller_design);
|
||||
|
||||
lv_roller_set_options(roller, "Option 1\nOption 2\nOption 3\nOption 4\nOption 5", LV_ROLLER_MODE_NORMAL);
|
||||
|
||||
lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal);
|
||||
|
||||
lv_obj_clean_style_list(roller, LV_PAGE_PART_SCROLLABLE); /*Use a transparent scrollable*/
|
||||
lv_theme_apply(roller, LV_THEME_ROLLER);
|
||||
refr_height(roller);
|
||||
|
||||
lv_roller_set_visible_row_count(roller, 3);
|
||||
}
|
||||
/*Copy an existing roller*/
|
||||
else {
|
||||
lv_label_create(roller, get_label(copy));
|
||||
lv_obj_t * label = lv_label_create(roller, get_label(copy));
|
||||
|
||||
lv_roller_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->mode = copy_ext->mode;
|
||||
ext->option_cnt = copy_ext->option_cnt;
|
||||
ext->sel_opt_id = copy_ext->sel_opt_id;
|
||||
ext->sel_opt_id_ori = copy_ext->sel_opt_id;
|
||||
ext->auto_fit = copy_ext->auto_fit;
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(roller);
|
||||
lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal);
|
||||
|
||||
lv_obj_set_design_cb(label, lv_roller_label_design);
|
||||
lv_obj_set_signal_cb(label, lv_roller_label_signal);
|
||||
|
||||
lv_obj_set_signal_cb(roller, lv_roller_signal);
|
||||
lv_obj_set_design_cb(roller, lv_roller_design);
|
||||
|
||||
lv_style_list_copy(&ext->style_sel, ©_ext->style_sel);
|
||||
lv_obj_refresh_style(roller, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(roller, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("roller created");
|
||||
@@ -193,12 +196,14 @@ void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mo
|
||||
ext->sel_opt_id = ((LV_ROLLER_INF_PAGES / 2) + 0) * ext->option_cnt;
|
||||
|
||||
ext->option_cnt = ext->option_cnt * LV_ROLLER_INF_PAGES;
|
||||
inf_normalize(roller);
|
||||
}
|
||||
|
||||
ext->sel_opt_id_ori = ext->sel_opt_id;
|
||||
|
||||
refr_height(roller);
|
||||
refr_width(roller);
|
||||
/*If the selected text has larger font the label needs some extra draw padding to draw it.*/
|
||||
_lv_obj_refresh_ext_draw_pad(label);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +219,7 @@ void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align)
|
||||
if(label == NULL) return; /*Probably the roller is being deleted if the label is NULL.*/
|
||||
|
||||
lv_label_set_align(label, align);
|
||||
refr_width(roller); /*To set the correct label position*/
|
||||
refr_position(roller, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,23 +276,19 @@ void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt)
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_obj_set_height(roller, (lv_font_get_line_height(font) + line_space) * row_cnt);
|
||||
|
||||
refr_height(roller);
|
||||
refr_position(roller, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow automatically setting the width of roller according to it's content.
|
||||
* Get the animation time of the roller
|
||||
* @param roller pointer to a roller object
|
||||
* @param auto_fit true: enable auto fit
|
||||
* @param the animation time in milliseconds
|
||||
*/
|
||||
void lv_roller_set_auto_fit(lv_obj_t * roller, bool auto_fit)
|
||||
void lv_roller_set_anim_time(lv_obj_t * roller, uint32_t anim_time)
|
||||
{
|
||||
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
ext->auto_fit = auto_fit;
|
||||
refr_width(roller);
|
||||
ext->anim_time = anim_time;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -375,18 +376,6 @@ lv_label_align_t lv_roller_get_align(const lv_obj_t * roller)
|
||||
return lv_label_get_align(get_label(roller));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the auto fit option is enabled or not.
|
||||
* @param roller pointer to a roller object
|
||||
* @return true: auto fit is enabled
|
||||
*/
|
||||
bool lv_roller_get_auto_fit(lv_obj_t * roller)
|
||||
{
|
||||
LV_ASSERT_OBJ(roller, LV_OBJX_NAME);
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
return ext->auto_fit ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options of a roller
|
||||
* @param roller pointer to roller object
|
||||
@@ -399,6 +388,16 @@ const char * lv_roller_get_options(const lv_obj_t * roller)
|
||||
return lv_label_get_text(get_label(roller));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the animation time of the roller
|
||||
* @param roller pointer to a roller object
|
||||
* @return the animation time in milliseconds
|
||||
*/
|
||||
uint32_t lv_roller_get_anim_time(lv_obj_t * roller)
|
||||
{
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
return ext->anim_time;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
@@ -417,22 +416,21 @@ const char * lv_roller_get_options(const lv_obj_t * roller)
|
||||
static lv_design_res_t lv_roller_design(lv_obj_t * roller, const lv_area_t * clip_area, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return LV_DESIGN_RES_NOT_COVER;
|
||||
return ancestor_design(roller, clip_area, mode);
|
||||
}
|
||||
/*Draw the object*/
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
draw_bg(roller, clip_area);
|
||||
ancestor_design(roller, clip_area, mode);
|
||||
|
||||
/*Draw the selected rectangle*/
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_area_t rect_area;
|
||||
rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - line_space / 2;
|
||||
if((font_h & 0x1) && (line_space & 0x1)) rect_area.y1--; /*Compensate the two rounding error*/
|
||||
rect_area.y1 = roller->coords.y1 + (lv_obj_get_height(roller) - font_h - line_space) / 2;
|
||||
rect_area.y2 = rect_area.y1 + font_h + line_space - 1;
|
||||
lv_area_t roller_coords;
|
||||
lv_obj_get_coords(roller, &roller_coords);
|
||||
lv_obj_get_inner_coords(roller, &roller_coords);
|
||||
|
||||
rect_area.x1 = roller_coords.x1;
|
||||
rect_area.x2 = roller_coords.x2;
|
||||
@@ -452,8 +450,7 @@ static lv_design_res_t lv_roller_design(lv_obj_t * roller, const lv_area_t * cli
|
||||
|
||||
/*Redraw the text on the selected area*/
|
||||
lv_area_t rect_area;
|
||||
rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - bg_font_h / 2 - label_dsc.line_space / 2;
|
||||
if((bg_font_h & 0x1) && (label_dsc.line_space & 0x1)) rect_area.y1--; /*Compensate the two rounding error*/
|
||||
rect_area.y1 = roller->coords.y1 + (lv_obj_get_height(roller) - bg_font_h - label_dsc.line_space) / 2;
|
||||
rect_area.y2 = rect_area.y1 + bg_font_h + label_dsc.line_space - 1;
|
||||
rect_area.x1 = roller->coords.x1;
|
||||
rect_area.x2 = roller->coords.x2;
|
||||
@@ -503,6 +500,8 @@ static lv_design_res_t lv_roller_design(lv_obj_t * roller, const lv_area_t * cli
|
||||
label_dsc.flag |= LV_TXT_FLAG_EXPAND;
|
||||
lv_draw_label(&label_sel_area, &mask_sel, &label_dsc, lv_label_get_text(label), NULL);
|
||||
}
|
||||
|
||||
ancestor_design(roller, clip_area, mode);
|
||||
}
|
||||
|
||||
return LV_DESIGN_RES_OK;
|
||||
@@ -528,18 +527,17 @@ static lv_design_res_t lv_roller_label_design(lv_obj_t * label, const lv_area_t
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/* Split the drawing of the label into an upper (above the selected area)
|
||||
* and a lower (below the selected area)*/
|
||||
lv_obj_t * roller = lv_obj_get_parent(lv_obj_get_parent(label));
|
||||
lv_obj_t * roller = lv_obj_get_parent(label);
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
|
||||
lv_area_t rect_area;
|
||||
rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - line_space / 2;
|
||||
rect_area.y1 = roller->coords.y1 + (lv_obj_get_height(roller) - font_h - line_space) / 2;
|
||||
if((font_h & 0x1) && (line_space & 0x1)) rect_area.y1--; /*Compensate the two rounding error*/
|
||||
rect_area.y2 = rect_area.y1 + font_h + line_space - 1;
|
||||
lv_area_t roller_coords;
|
||||
lv_obj_get_coords(roller, &roller_coords);
|
||||
lv_obj_get_inner_coords(roller, &roller_coords);
|
||||
|
||||
rect_area.x1 = roller_coords.x1;
|
||||
rect_area.x2 = roller_coords.x2;
|
||||
@@ -574,44 +572,55 @@ static lv_design_res_t lv_roller_label_design(lv_obj_t * label, const lv_area_t
|
||||
*/
|
||||
static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res = LV_RES_OK;
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(roller, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
|
||||
/* Include the ancient signal function */
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_roller_get_style(roller, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(roller, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
if(sign != LV_SIGNAL_CONTROL) { /*Don't let the page to scroll on keys*/
|
||||
res = ancestor_signal(roller, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
LV_UNUSED(ext);
|
||||
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
else if(sign == LV_SIGNAL_GET_SELF_SIZE) {
|
||||
lv_point_t * p = param;
|
||||
p->x = get_selected_label_width(roller);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_t * label = get_label(roller);
|
||||
/*Be sure the label's style is updated before processing the roller*/
|
||||
if(label) lv_signal_send(label, LV_SIGNAL_STYLE_CHG, NULL);
|
||||
refr_height(roller);
|
||||
refr_width(roller);
|
||||
_lv_obj_handle_self_size_chg(roller);
|
||||
refr_position(roller, false);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
|
||||
if(lv_obj_get_width(roller) != lv_area_get_width(param) ||
|
||||
lv_obj_get_height(roller) != lv_area_get_height(param)) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(lv_page_get_scrollable(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
lv_obj_get_height(roller) != lv_area_get_height(param))
|
||||
{
|
||||
refr_position(roller, false);
|
||||
refr_width(roller);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED) {
|
||||
ext->moved = 0;
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(get_label(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSING) {
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_point_t p;
|
||||
lv_indev_get_vect(indev, &p);
|
||||
lv_obj_t * label = get_label(roller);
|
||||
lv_obj_set_y(label, lv_obj_get_y(label) + p.y);
|
||||
if(p.y) ext->moved = 1;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
release_handler(roller);
|
||||
}
|
||||
@@ -671,8 +680,36 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(roller, LV_ROLLER_PART_SELECTED);
|
||||
_lv_obj_reset_style_list_no_refr(roller, LV_ROLLER_PART_SELECTED);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the roller's label
|
||||
* @param label pointer to a roller's label object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_roller_label_signal(lv_obj_t * label, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_label_signal(label, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
|
||||
/*If the selected text has a larger font it needs some extra space to draw it*/
|
||||
lv_coord_t * s = param;
|
||||
lv_obj_t * roller = lv_obj_get_parent(label);
|
||||
lv_coord_t sel_w = get_selected_label_width(roller);
|
||||
lv_coord_t label_w = lv_obj_get_width(label);
|
||||
*s = LV_MATH_MAX(*s, sel_w - label_w);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -703,132 +740,6 @@ static lv_style_list_t * lv_roller_get_style(lv_obj_t * roller, uint8_t part)
|
||||
return style_dsc_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal function of the scrollable part of the roller.
|
||||
* @param roller_scrl pointer to the scrollable part of roller (page)
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_scrl_signal(roller_scrl, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_obj_t * roller = lv_obj_get_parent(roller_scrl);
|
||||
|
||||
/*On delete the ddlist signal deletes the label so nothing left to do here*/
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return LV_RES_INV;
|
||||
|
||||
int32_t id = -1;
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
|
||||
if(sign == LV_SIGNAL_DRAG_END) {
|
||||
/*If dragged then align the list to have an element in the middle*/
|
||||
lv_coord_t label_y1 = label->coords.y1 - roller->coords.y1;
|
||||
lv_coord_t label_unit = font_h + line_space;
|
||||
lv_coord_t mid = (roller->coords.y2 - roller->coords.y1) / 2;
|
||||
|
||||
id = (mid - label_y1 + line_space / 2) / label_unit;
|
||||
|
||||
if(id < 0) id = 0;
|
||||
if(id >= ext->option_cnt) id = ext->option_cnt - 1;
|
||||
|
||||
ext->sel_opt_id = id;
|
||||
ext->sel_opt_id_ori = id;
|
||||
res = lv_event_send(roller, LV_EVENT_VALUE_CHANGED, &id);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
/*If picked an option by clicking then set it*/
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
release_handler(roller);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSED) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(roller_scrl, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(lv_page_get_scrollable(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
refr_position(roller, false);
|
||||
refr_width(roller);
|
||||
|
||||
}
|
||||
|
||||
/*Position the scrollable according to the new selected option*/
|
||||
if(id != -1) {
|
||||
refr_position(roller, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a rectangle which has gradient on its top and bottom
|
||||
* @param roller pointer to a roller object
|
||||
* @param clip_area pointer to the current mask (from the design function)
|
||||
*/
|
||||
static void draw_bg(lv_obj_t * roller, const lv_area_t * clip_area)
|
||||
{
|
||||
lv_draw_rect_dsc_t bg_dsc;
|
||||
lv_draw_rect_dsc_init(&bg_dsc);
|
||||
lv_obj_init_draw_rect_dsc(roller, LV_ROLLER_PART_BG, &bg_dsc);
|
||||
|
||||
/*With non-vertical gradient simply draw the background*/
|
||||
if(bg_dsc.bg_grad_dir == LV_GRAD_DIR_NONE) {
|
||||
lv_draw_rect(&roller->coords, clip_area, &bg_dsc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*With vertical gradient mirror it*/
|
||||
|
||||
lv_area_t half_mask;
|
||||
lv_coord_t h = lv_obj_get_height(roller);
|
||||
bool union_ok;
|
||||
|
||||
lv_area_copy(&half_mask, &roller->coords);
|
||||
half_mask.x1 -= roller->ext_draw_pad; /*Add ext size too (e.g. because of shadow draw) */
|
||||
half_mask.x2 += roller->ext_draw_pad;
|
||||
half_mask.y1 -= roller->ext_draw_pad;
|
||||
half_mask.y2 = roller->coords.y1 + h / 2;
|
||||
|
||||
union_ok = _lv_area_intersect(&half_mask, &half_mask, clip_area);
|
||||
bg_dsc.bg_main_color_stop = bg_dsc.bg_main_color_stop / 2;
|
||||
bg_dsc.bg_grad_color_stop = 128 - (255 - bg_dsc.bg_grad_color_stop) / 2;
|
||||
if(union_ok) {
|
||||
lv_draw_rect(&roller->coords, &half_mask, &bg_dsc);
|
||||
}
|
||||
|
||||
lv_area_copy(&half_mask, &roller->coords);
|
||||
half_mask.x1 -= roller->ext_draw_pad; /*Revert ext. size adding*/
|
||||
half_mask.x2 += roller->ext_draw_pad;
|
||||
half_mask.y1 = roller->coords.y1 + h / 2;
|
||||
half_mask.y2 += roller->ext_draw_pad;
|
||||
|
||||
union_ok = _lv_area_intersect(&half_mask, &half_mask, clip_area);
|
||||
if(union_ok) {
|
||||
lv_color_t c = bg_dsc.bg_color;
|
||||
bg_dsc.bg_color = bg_dsc.bg_grad_color;
|
||||
bg_dsc.bg_grad_color = c;
|
||||
|
||||
bg_dsc.bg_main_color_stop += 127;
|
||||
bg_dsc.bg_grad_color_stop += 127;
|
||||
lv_draw_rect(&roller->coords, &half_mask, &bg_dsc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the position of the roller. It uses the id stored in: ext->ddlist.selected_option_id
|
||||
* @param roller pointer to a roller object
|
||||
@@ -836,45 +747,65 @@ static void draw_bg(lv_obj_t * roller, const lv_area_t * clip_area)
|
||||
*/
|
||||
static void refr_position(lv_obj_t * roller, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return;
|
||||
|
||||
#if LV_USE_ANIMATION == 0
|
||||
anim_en = LV_ANIM_OFF;
|
||||
#endif
|
||||
|
||||
lv_obj_t * roller_scrl = lv_page_get_scrollable(roller);
|
||||
lv_label_align_t align = lv_label_get_align(label);
|
||||
switch(align) {
|
||||
case LV_LABEL_ALIGN_CENTER:
|
||||
lv_obj_set_x(label, (lv_obj_get_width_fit(roller) - lv_obj_get_width(label)) / 2);
|
||||
break;
|
||||
case LV_LABEL_ALIGN_RIGHT:
|
||||
lv_obj_set_x(label, lv_obj_get_width_fit(roller) - lv_obj_get_width(label));
|
||||
break;
|
||||
case LV_LABEL_ALIGN_LEFT:
|
||||
lv_obj_set_x(label, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_coord_t h = lv_obj_get_height(roller);
|
||||
lv_coord_t h = lv_obj_get_height_fit(roller);
|
||||
uint16_t anim_time = lv_roller_get_anim_time(roller);
|
||||
|
||||
/* Normally the animation's `end_cb` sets correct position of the roller if infinite.
|
||||
* But without animations do it manually*/
|
||||
if(anim_en == LV_ANIM_OFF || anim_time == 0) {
|
||||
inf_normalize(roller_scrl);
|
||||
inf_normalize(roller);
|
||||
}
|
||||
|
||||
lv_obj_t * label = get_label(roller);
|
||||
|
||||
int32_t id = ext->sel_opt_id;
|
||||
lv_coord_t line_y1 = id * (font_h + line_space) + label->coords.y1 - roller_scrl->coords.y1;
|
||||
lv_coord_t new_y = -line_y1 + (h - font_h) / 2;
|
||||
lv_coord_t sel_y1 = id * (font_h + line_space);
|
||||
lv_coord_t mid_y1 = h / 2 - font_h / 2;
|
||||
|
||||
lv_coord_t new_y = mid_y1 - sel_y1;
|
||||
|
||||
if(anim_en == LV_ANIM_OFF || anim_time == 0) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(roller_scrl, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
lv_anim_del(label, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
lv_obj_set_y(roller_scrl, new_y);
|
||||
lv_obj_set_y(label, new_y);
|
||||
}
|
||||
else {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_path_t path;
|
||||
lv_anim_path_init(&path);
|
||||
lv_anim_path_set_cb(&path, lv_anim_path_ease_out);
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, roller_scrl);
|
||||
lv_anim_set_var(&a, label);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
lv_anim_set_values(&a, lv_obj_get_y(roller_scrl), new_y);
|
||||
lv_anim_set_values(&a, lv_obj_get_y(label), new_y);
|
||||
lv_anim_set_time(&a, anim_time);
|
||||
lv_anim_set_ready_cb(&a, scroll_anim_ready_cb);
|
||||
lv_anim_set_path(&a, &path);
|
||||
lv_anim_start(&a);
|
||||
#endif
|
||||
}
|
||||
@@ -884,12 +815,12 @@ static void refr_position(lv_obj_t * roller, lv_anim_enable_t anim_en)
|
||||
static lv_res_t release_handler(lv_obj_t * roller)
|
||||
{
|
||||
|
||||
/*If there was dragging `DRAG_END` signal will refresh the position and update the selected option*/
|
||||
if(lv_indev_is_dragging(lv_indev_get_act())) return LV_RES_OK;
|
||||
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return LV_RES_OK;
|
||||
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/*Leave edit mode once a new option is selected*/
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
@@ -905,32 +836,50 @@ static lv_res_t release_handler(lv_obj_t * roller)
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return LV_RES_OK;
|
||||
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {
|
||||
/*Search the clicked option (For KEYPAD and ENCODER the new value should be already set)*/
|
||||
uint16_t new_opt = 0;
|
||||
lv_point_t p;
|
||||
lv_indev_get_point(indev, &p);
|
||||
p.y -= label->coords.y1;
|
||||
p.x -= label->coords.x1;
|
||||
uint32_t letter_i;
|
||||
letter_i = lv_label_get_letter_on(label, &p);
|
||||
int16_t new_opt = -1;
|
||||
if(ext->moved == 0) {
|
||||
new_opt = 0;
|
||||
lv_point_t p;
|
||||
lv_indev_get_point(indev, &p);
|
||||
p.y -= label->coords.y1;
|
||||
p.x -= label->coords.x1;
|
||||
uint32_t letter_i;
|
||||
letter_i = lv_label_get_letter_on(label, &p);
|
||||
|
||||
const char * txt = lv_label_get_text(label);
|
||||
uint32_t i = 0;
|
||||
uint32_t i_prev = 0;
|
||||
const char * txt = lv_label_get_text(label);
|
||||
uint32_t i = 0;
|
||||
uint32_t i_prev = 0;
|
||||
|
||||
uint32_t letter_cnt = 0;
|
||||
for(letter_cnt = 0; letter_cnt < letter_i; letter_cnt++) {
|
||||
uint32_t letter = _lv_txt_encoded_next(txt, &i);
|
||||
/*Count he lines to reach the clicked letter. But ignore the last '\n' because it
|
||||
* still belongs to the clicked line*/
|
||||
if(letter == '\n' && i_prev != letter_i) new_opt++;
|
||||
i_prev = i;
|
||||
uint32_t letter_cnt = 0;
|
||||
for(letter_cnt = 0; letter_cnt < letter_i; letter_cnt++) {
|
||||
uint32_t letter = _lv_txt_encoded_next(txt, &i);
|
||||
/*Count he lines to reach the clicked letter. But ignore the last '\n' because it
|
||||
* still belongs to the clicked line*/
|
||||
if(letter == '\n' && i_prev != letter_i) new_opt++;
|
||||
i_prev = i;
|
||||
}
|
||||
} else {
|
||||
/*If dragged then align the list to have an element in the middle*/
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
|
||||
lv_coord_t label_unit = font_h + line_space;
|
||||
lv_coord_t mid = roller->coords.y1 + (roller->coords.y2 - roller->coords.y1) / 2;
|
||||
lv_coord_t label_y1 = label->coords.y1 + _lv_scroll_throw_predict(indev, LV_DIR_VER);
|
||||
int32_t id = (mid - label_y1) / label_unit;
|
||||
|
||||
if(id < 0) id = 0;
|
||||
if(id >= ext->option_cnt) id = ext->option_cnt - 1;
|
||||
|
||||
new_opt = id;
|
||||
}
|
||||
|
||||
if(new_opt >= 0) {
|
||||
lv_roller_set_selected(roller, new_opt, LV_ANIM_ON);
|
||||
}
|
||||
lv_roller_set_selected(roller, new_opt, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
uint32_t id = ext->sel_opt_id; /*Just to use uint32_t in event data*/
|
||||
@@ -938,71 +887,12 @@ static lv_res_t release_handler(lv_obj_t * roller)
|
||||
return res;
|
||||
}
|
||||
|
||||
static void refr_width(lv_obj_t * roller)
|
||||
{
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return;
|
||||
|
||||
switch(lv_label_get_align(label)) {
|
||||
case LV_LABEL_ALIGN_LEFT:
|
||||
lv_obj_align(label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0);
|
||||
break;
|
||||
case LV_LABEL_ALIGN_CENTER:
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
break;
|
||||
case LV_LABEL_ALIGN_RIGHT:
|
||||
lv_obj_align(label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(lv_roller_get_auto_fit(roller) == false) return;
|
||||
|
||||
lv_coord_t label_w = lv_obj_get_width(label);
|
||||
|
||||
lv_style_int_t left = lv_obj_get_style_pad_left(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t right = lv_obj_get_style_pad_right(roller, LV_ROLLER_PART_BG);
|
||||
|
||||
const lv_font_t * base_font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
const lv_font_t * sel_font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_SELECTED);
|
||||
|
||||
/*The selected text might be larger to get its size*/
|
||||
if(base_font != sel_font) {
|
||||
lv_coord_t letter_sp = lv_obj_get_style_text_letter_space(roller, LV_ROLLER_PART_SELECTED);
|
||||
lv_coord_t line_sp = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_SELECTED);
|
||||
lv_point_t p;
|
||||
_lv_txt_get_size(&p, lv_label_get_text(label), sel_font, letter_sp, line_sp, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
if(label_w < p.x)label_w = p.x;
|
||||
}
|
||||
|
||||
lv_obj_set_width(roller, label_w + left + right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the height of the roller and the scrollable
|
||||
* @param roller pointer to roller
|
||||
*/
|
||||
static void refr_height(lv_obj_t * roller)
|
||||
{
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return;
|
||||
|
||||
lv_obj_set_height(lv_page_get_scrollable(roller), lv_obj_get_height(label) + lv_obj_get_height(roller));
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
lv_anim_del(lv_page_get_scrollable(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);
|
||||
#endif
|
||||
refr_position(roller, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the middle page for the roller if infinite is enabled
|
||||
* @param scrl pointer to the roller's scrollable (lv_obj_t *)
|
||||
* @param roller pointer to a roller object
|
||||
*/
|
||||
static void inf_normalize(void * scrl)
|
||||
static void inf_normalize(lv_obj_t * roller)
|
||||
{
|
||||
lv_obj_t * roller_scrl = (lv_obj_t *)scrl;
|
||||
lv_obj_t * roller = lv_obj_get_parent(roller_scrl);
|
||||
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
|
||||
|
||||
if(ext->mode == LV_ROLLER_MODE_INIFINITE) {
|
||||
@@ -1017,27 +907,42 @@ static void inf_normalize(void * scrl)
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG);
|
||||
lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG);
|
||||
lv_coord_t font_h = lv_font_get_line_height(font);
|
||||
lv_coord_t h = lv_obj_get_height(roller);
|
||||
lv_coord_t h = lv_obj_get_height_fit(roller);
|
||||
|
||||
lv_obj_t * label = get_label(roller);
|
||||
|
||||
lv_coord_t line_y1 = ext->sel_opt_id * (font_h + line_space) + label->coords.y1 - roller_scrl->coords.y1;
|
||||
lv_coord_t new_y = -line_y1 + (h - font_h) / 2;
|
||||
lv_obj_set_y(roller_scrl, new_y);
|
||||
|
||||
lv_coord_t sel_y1 = ext->sel_opt_id * (font_h + line_space);
|
||||
lv_coord_t mid_y1 = h / 2 - font_h / 2;
|
||||
lv_coord_t new_y = mid_y1 - sel_y1;
|
||||
lv_obj_set_y(label, new_y);
|
||||
}
|
||||
}
|
||||
|
||||
static lv_obj_t * get_label(const lv_obj_t * roller)
|
||||
{
|
||||
lv_obj_t * scrl = lv_page_get_scrollable(roller);
|
||||
if(scrl == NULL) return NULL; /*The roller is being deleted, the scrollable already not exists*/
|
||||
return lv_obj_get_child(scrl, NULL);
|
||||
return lv_obj_get_child(roller, NULL);
|
||||
}
|
||||
|
||||
|
||||
static lv_coord_t get_selected_label_width(const lv_obj_t * roller)
|
||||
{
|
||||
lv_obj_t * label = get_label(roller);
|
||||
if(label == NULL) return 0;
|
||||
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_SELECTED);
|
||||
lv_style_int_t letter_space = lv_obj_get_style_text_letter_space(roller, LV_ROLLER_PART_SELECTED);
|
||||
const char * txt = lv_label_get_text(label);
|
||||
lv_point_t size;
|
||||
_lv_txt_get_size(&size, txt, font, letter_space, 0, LV_COORD_MAX, LV_TXT_FLAG_NONE);
|
||||
return size.x;
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
static void scroll_anim_ready_cb(lv_anim_t * a)
|
||||
{
|
||||
inf_normalize(a->var);
|
||||
lv_obj_t * roller = lv_obj_get_parent(a->var); /*The label is animated*/
|
||||
inf_normalize(roller);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,13 +17,7 @@ extern "C" {
|
||||
|
||||
#if LV_USE_ROLLER != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_PAGE == 0
|
||||
#error "lv_roller: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_page.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
/*********************
|
||||
@@ -46,20 +40,21 @@ typedef uint8_t lv_roller_mode_t;
|
||||
|
||||
/*Data of roller*/
|
||||
typedef struct {
|
||||
lv_page_ext_t page; /*Ext. of ancestor*/
|
||||
/*No inherited ext.*/ /*Ext. of ancestor*/
|
||||
|
||||
/*New data for this type */
|
||||
lv_style_list_t style_sel; /*Style of the selected option*/
|
||||
uint16_t option_cnt; /*Number of options*/
|
||||
uint16_t sel_opt_id; /*Index of the current option*/
|
||||
uint16_t sel_opt_id_ori; /*Store the original index on focus*/
|
||||
uint32_t anim_time;
|
||||
lv_roller_mode_t mode : 1;
|
||||
uint8_t auto_fit : 1; /*1: Automatically set the width*/
|
||||
uint32_t moved : 1;
|
||||
} lv_roller_ext_t;
|
||||
|
||||
enum {
|
||||
LV_ROLLER_PART_BG = LV_PAGE_PART_BG,
|
||||
LV_ROLLER_PART_SELECTED = _LV_PAGE_PART_VIRTUAL_LAST,
|
||||
LV_ROLLER_PART_BG = LV_OBJ_PART_MAIN,
|
||||
LV_ROLLER_PART_SELECTED,
|
||||
_LV_ROLLER_PART_VIRTUAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_roller_part_t;
|
||||
@@ -111,21 +106,11 @@ void lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_
|
||||
void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt);
|
||||
|
||||
/**
|
||||
* Allow automatically setting the width of roller according to it's content.
|
||||
* Get the animation time of the roller
|
||||
* @param roller pointer to a roller object
|
||||
* @param auto_fit true: enable auto fit
|
||||
* @param the animation time in milliseconds
|
||||
*/
|
||||
void lv_roller_set_auto_fit(lv_obj_t * roller, bool auto_fit);
|
||||
|
||||
/**
|
||||
* Set the open/close animation time.
|
||||
* @param roller pointer to a roller object
|
||||
* @param anim_time: open/close animation time [ms]
|
||||
*/
|
||||
static inline void lv_roller_set_anim_time(lv_obj_t * roller, uint16_t anim_time)
|
||||
{
|
||||
lv_page_set_anim_time(roller, anim_time);
|
||||
}
|
||||
void lv_roller_set_anim_time(lv_obj_t * roller, uint32_t anim_time);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
@@ -159,13 +144,6 @@ void lv_roller_get_selected_str(const lv_obj_t * roller, char * buf, uint32_t bu
|
||||
*/
|
||||
lv_label_align_t lv_roller_get_align(const lv_obj_t * roller);
|
||||
|
||||
/**
|
||||
* Get whether the auto fit option is enabled or not.
|
||||
* @param roller pointer to a roller object
|
||||
* @return true: auto fit is enabled
|
||||
*/
|
||||
bool lv_roller_get_auto_fit(lv_obj_t * roller);
|
||||
|
||||
/**
|
||||
* Get the options of a roller
|
||||
* @param roller pointer to roller object
|
||||
@@ -173,15 +151,6 @@ bool lv_roller_get_auto_fit(lv_obj_t * roller);
|
||||
*/
|
||||
const char * lv_roller_get_options(const lv_obj_t * roller);
|
||||
|
||||
/**
|
||||
* Get the open/close animation time.
|
||||
* @param roller pointer to a roller
|
||||
* @return open/close animation time [ms]
|
||||
*/
|
||||
static inline uint16_t lv_roller_get_anim_time(const lv_obj_t * roller)
|
||||
{
|
||||
return lv_page_get_anim_time(roller);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -41,7 +41,7 @@ static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area,
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_cb_t ancestor_design_f;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**********************
|
||||
@@ -54,20 +54,21 @@ static lv_signal_cb_t ancestor_signal;
|
||||
|
||||
/**
|
||||
* Create a slider objects
|
||||
* @param par pointer to an object, it will be the parent of the new slider
|
||||
* @param copy pointer to a slider object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new slider
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other slider to copy.
|
||||
* @return pointer to the created slider
|
||||
*/
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("slider create started");
|
||||
|
||||
/*Create the ancestor slider*/
|
||||
lv_obj_t * slider = lv_bar_create(par, copy);
|
||||
lv_obj_t * slider = lv_bar_create(parent, copy);
|
||||
LV_ASSERT_MEM(slider);
|
||||
if(slider == NULL) return NULL;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(slider);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(slider);
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(slider);
|
||||
|
||||
/*Allocate the slider type specific extended data*/
|
||||
@@ -89,23 +90,20 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new slider slider*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_click(slider, true);
|
||||
lv_obj_add_protect(slider, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_set_ext_click_area(slider, 0, 0, LV_DPI / 10, LV_DPI / 10);
|
||||
|
||||
lv_theme_apply(slider, LV_THEME_SLIDER);
|
||||
lv_obj_add_flag(slider, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_set_ext_click_area(slider, 0, 0, LV_DPI / 10, LV_DPI / 10);
|
||||
lv_obj_set_height(slider, LV_DPI / 15);
|
||||
}
|
||||
/*Copy an existing slider*/
|
||||
else {
|
||||
} else {
|
||||
lv_slider_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
lv_style_list_copy(&ext->style_knob, ©_ext->style_knob);
|
||||
lv_area_copy(&ext->left_knob_area, ©_ext->left_knob_area);
|
||||
lv_area_copy(&ext->right_knob_area, ©_ext->right_knob_area);
|
||||
|
||||
lv_obj_refresh_style(slider, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(slider, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_INFO("slider created");
|
||||
|
||||
return slider;
|
||||
@@ -119,17 +117,6 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the value of a slider
|
||||
* @param slider pointer to a slider object
|
||||
* @return the value of the slider
|
||||
*/
|
||||
int16_t lv_slider_get_value(const lv_obj_t * slider)
|
||||
{
|
||||
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
|
||||
return lv_bar_get_value(slider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the slider is being dragged or not
|
||||
* @param slider pointer to a slider object
|
||||
@@ -167,7 +154,7 @@ static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * cli
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/* The ancestor design function will draw the background and the indicator.
|
||||
* It also sets ext->bar.indic_area*/
|
||||
ancestor_design_f(slider, clip_area, mode);
|
||||
ancestor_design(slider, clip_area, mode);
|
||||
|
||||
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(slider);
|
||||
@@ -230,7 +217,7 @@ static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * cli
|
||||
}
|
||||
/*Post draw when the children are drawn*/
|
||||
else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
return ancestor_design_f(slider, clip_area, mode);
|
||||
return ancestor_design(slider, clip_area, mode);
|
||||
}
|
||||
|
||||
return LV_DESIGN_RES_OK;
|
||||
@@ -257,7 +244,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(slider, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
lv_slider_type_t type = lv_slider_get_type(slider);
|
||||
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
|
||||
@@ -333,10 +320,10 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
|
||||
lv_coord_t w = lv_obj_get_width(slider);
|
||||
lv_coord_t h = lv_obj_get_height(slider);
|
||||
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(slider, LV_SLIDER_PART_BG);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(slider, LV_SLIDER_PART_BG);
|
||||
lv_style_int_t bg_top = lv_obj_get_style_pad_top(slider, LV_SLIDER_PART_BG);
|
||||
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(slider, LV_SLIDER_PART_BG);
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(slider, LV_SLIDER_PART_MAIN);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(slider, LV_SLIDER_PART_MAIN);
|
||||
lv_style_int_t bg_top = lv_obj_get_style_pad_top(slider, LV_SLIDER_PART_MAIN);
|
||||
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(slider, LV_SLIDER_PART_MAIN);
|
||||
|
||||
int32_t range = ext->bar.max_value - ext->bar.min_value;
|
||||
int16_t new_value = 0;
|
||||
@@ -414,10 +401,11 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
|
||||
knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top));
|
||||
knob_size += 2; /*For rounding error*/
|
||||
|
||||
knob_size += lv_obj_get_draw_rect_ext_pad_size(slider, LV_SLIDER_PART_KNOB);
|
||||
knob_size += _lv_obj_get_draw_rect_ext_pad_size(slider, LV_SLIDER_PART_KNOB);
|
||||
|
||||
/*Indic. size is handled by bar*/
|
||||
slider->ext_draw_pad = LV_MATH_MAX(slider->ext_draw_pad, knob_size);
|
||||
lv_coord_t * s = param;
|
||||
*s = LV_MATH_MAX(*s, knob_size);
|
||||
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
@@ -437,7 +425,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
|
||||
#endif
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(slider, LV_SLIDER_PART_KNOB);
|
||||
_lv_obj_reset_style_list_no_refr(slider, LV_SLIDER_PART_KNOB);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
#if LV_USE_GROUP
|
||||
@@ -458,7 +446,7 @@ static lv_style_list_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part)
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_SLIDER_PART_BG:
|
||||
case LV_SLIDER_PART_MAIN:
|
||||
style_dsc_p = &slider->style_list;
|
||||
break;
|
||||
case LV_SLIDER_PART_INDIC:
|
||||
|
||||
@@ -53,9 +53,10 @@ typedef struct {
|
||||
|
||||
/** Built-in styles of slider*/
|
||||
enum {
|
||||
LV_SLIDER_PART_BG, /** Slider background style. */
|
||||
LV_SLIDER_PART_INDIC, /** Slider indicator (filled area) style. */
|
||||
LV_SLIDER_PART_KNOB, /** Slider knob style. */
|
||||
LV_SLIDER_PART_MAIN = LV_BAR_PART_MAIN, /** Slider background style. */
|
||||
LV_SLIDER_PART_INDIC = LV_BAR_PART_INDIC, /** Slider indicator (filled area) style. */
|
||||
LV_SLIDER_PART_KNOB = _LV_BAR_PART_VIRTUAL_LAST, /** Slider knob style. */
|
||||
_LV_SLIDER_PART_VIRTUAL_LAST
|
||||
};
|
||||
|
||||
/**********************
|
||||
@@ -64,11 +65,12 @@ enum {
|
||||
|
||||
/**
|
||||
* Create a slider objects
|
||||
* @param par pointer to an object, it will be the parent of the new slider
|
||||
* @param copy pointer to a slider object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new slider
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other slider to copy.
|
||||
* @return pointer to the created slider
|
||||
*/
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * parent, lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
@@ -142,7 +144,10 @@ static inline void lv_slider_set_type(lv_obj_t * slider, lv_slider_type_t type)
|
||||
* @param slider pointer to a slider object
|
||||
* @return the value of the main knob of the slider
|
||||
*/
|
||||
int16_t lv_slider_get_value(const lv_obj_t * slider);
|
||||
static inline int16_t lv_slider_get_value(const lv_obj_t * slider)
|
||||
{
|
||||
return lv_bar_get_value(slider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the left knob of a slider
|
||||
|
||||
@@ -1,605 +0,0 @@
|
||||
/**
|
||||
* @file lv_spinbox.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_spinbox.h"
|
||||
|
||||
#if LV_USE_SPINBOX != 0
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_spinbox"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * param);
|
||||
static lv_style_list_t * lv_spinbox_get_style(lv_obj_t * ta, uint8_t part);
|
||||
static void lv_spinbox_updatevalue(lv_obj_t * spinbox);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a spinbox object
|
||||
* @param par pointer to an object, it will be the parent of the new spinbox
|
||||
* @param copy pointer to a spinbox object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created spinbox
|
||||
*/
|
||||
lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("spinbox create started");
|
||||
|
||||
/*Create the ancestor of spinbox*/
|
||||
lv_obj_t * spinbox = lv_textarea_create(par, copy);
|
||||
LV_ASSERT_MEM(spinbox);
|
||||
if(spinbox == NULL) return NULL;
|
||||
|
||||
/*Allocate the spinbox type specific extended data*/
|
||||
lv_spinbox_ext_t * ext = lv_obj_allocate_ext_attr(spinbox, sizeof(lv_spinbox_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(spinbox);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(spinbox);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(spinbox);
|
||||
|
||||
/*Initialize the allocated 'ext'*/
|
||||
ext->value = 0;
|
||||
ext->dec_point_pos = 0;
|
||||
ext->digit_count = 5;
|
||||
ext->digit_padding_left = 0;
|
||||
ext->step = 1;
|
||||
ext->range_max = 99999;
|
||||
ext->range_min = -99999;
|
||||
ext->rollover = false;
|
||||
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(spinbox, lv_spinbox_signal);
|
||||
lv_obj_set_design_cb(spinbox, ancestor_design); /*Leave the Text area's design function*/
|
||||
|
||||
/*Init the new spinbox*/
|
||||
if(copy == NULL) {
|
||||
/* No scrolling will happen here so make the scrollable non-clickable
|
||||
* It allows to handle input events in the bg object only.*/
|
||||
lv_obj_set_click(lv_page_get_scrollable(spinbox), false);
|
||||
lv_textarea_set_one_line(spinbox, true);
|
||||
lv_textarea_set_cursor_click_pos(spinbox, true);
|
||||
lv_obj_set_width(spinbox, LV_DPI);
|
||||
lv_theme_apply(spinbox, LV_THEME_SPINBOX);
|
||||
}
|
||||
/*Copy an existing spinbox*/
|
||||
else {
|
||||
lv_spinbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
|
||||
lv_spinbox_set_value(spinbox, copy_ext->value);
|
||||
lv_spinbox_set_digit_format(spinbox, (uint8_t)copy_ext->digit_count, (uint8_t)copy_ext->dec_point_pos);
|
||||
lv_spinbox_set_range(spinbox, copy_ext->range_min, copy_ext->range_max);
|
||||
lv_spinbox_set_step(spinbox, copy_ext->step);
|
||||
lv_spinbox_set_rollover(spinbox, copy_ext->rollover);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(spinbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
|
||||
LV_LOG_INFO("spinbox created");
|
||||
|
||||
return spinbox;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set spinbox rollover function
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param b true or false to enable or disable (default)
|
||||
*/
|
||||
void lv_spinbox_set_rollover(lv_obj_t * spinbox, bool b)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
ext->rollover = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spinbox value
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param i value to be set
|
||||
*/
|
||||
void lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
if(ext == NULL) return;
|
||||
|
||||
if(i > ext->range_max) i = ext->range_max;
|
||||
if(i < ext->range_min) i = ext->range_min;
|
||||
|
||||
ext->value = i;
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spinbox digit format (digit count and decimal format)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param digit_count number of digit excluding the decimal separator and the sign
|
||||
* @param separator_position number of digit before the decimal point. If 0, decimal point is not
|
||||
* shown
|
||||
*/
|
||||
void lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_t separator_position)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
if(ext == NULL) return;
|
||||
|
||||
if(digit_count > LV_SPINBOX_MAX_DIGIT_COUNT) digit_count = LV_SPINBOX_MAX_DIGIT_COUNT;
|
||||
|
||||
if(separator_position >= digit_count) separator_position = 0;
|
||||
if(separator_position > LV_SPINBOX_MAX_DIGIT_COUNT) separator_position = LV_SPINBOX_MAX_DIGIT_COUNT;
|
||||
|
||||
if(digit_count < LV_SPINBOX_MAX_DIGIT_COUNT) {
|
||||
int64_t max_val = _lv_pow(10, digit_count);
|
||||
if(ext->range_max > max_val - 1) ext->range_max = max_val - 1;
|
||||
if(ext->range_min < - max_val + 1) ext->range_min = - max_val + 1;
|
||||
}
|
||||
|
||||
ext->digit_count = digit_count;
|
||||
ext->dec_point_pos = separator_position;
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spinbox step
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param step steps on increment/decrement
|
||||
*/
|
||||
void lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
if(ext == NULL) return;
|
||||
|
||||
ext->step = step;
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spinbox value range
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param range_min maximum value, inclusive
|
||||
* @param range_max minimum value, inclusive
|
||||
*/
|
||||
void lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_max)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
if(ext == NULL) return;
|
||||
|
||||
ext->range_max = range_max;
|
||||
ext->range_min = range_min;
|
||||
|
||||
if(ext->value > ext->range_max) {
|
||||
ext->value = ext->range_max;
|
||||
lv_obj_invalidate(spinbox);
|
||||
}
|
||||
if(ext->value < ext->range_min) {
|
||||
ext->value = ext->range_min;
|
||||
lv_obj_invalidate(spinbox);
|
||||
}
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set spinbox left padding in digits count (added between sign and first digit)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param cb Callback function called on value change event
|
||||
*/
|
||||
void lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
ext->digit_padding_left = padding;
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get spinbox rollover function status
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
bool lv_spinbox_get_rollover(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
return ext->rollover;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spinbox numeral value (user has to convert to float according to its digit format)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @return value integer value of the spinbox
|
||||
*/
|
||||
int32_t lv_spinbox_get_value(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
return ext->value;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Select next lower digit for edition
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_step_next(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
int32_t new_step = ext->step / 10;
|
||||
if((new_step) > 0)
|
||||
ext->step = new_step;
|
||||
else
|
||||
ext->step = 1;
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select next higher digit for edition
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_step_prev(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
int32_t step_limit;
|
||||
step_limit = LV_MATH_MAX(ext->range_max, (ext->range_min < 0 ? (-ext->range_min) : ext->range_min));
|
||||
int32_t new_step = ext->step * 10;
|
||||
if(new_step <= step_limit) ext->step = new_step;
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment spinbox value by one step
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_increment(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
if(ext->value + ext->step <= ext->range_max) {
|
||||
/*Special mode when zero crossing*/
|
||||
if((ext->value + ext->step) > 0 && ext->value < 0) ext->value = -ext->value;
|
||||
ext->value += ext->step;
|
||||
|
||||
}
|
||||
else {
|
||||
// Rollover?
|
||||
if((ext->rollover) && (ext->value == ext->range_max))
|
||||
ext->value = ext->range_min;
|
||||
else
|
||||
ext->value = ext->range_max;
|
||||
}
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement spinbox value by one step
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_decrement(lv_obj_t * spinbox)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinbox, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
if(ext->value - ext->step >= ext->range_min) {
|
||||
/*Special mode when zero crossing*/
|
||||
if((ext->value - ext->step) < 0 && ext->value > 0) ext->value = -ext->value;
|
||||
ext->value -= ext->step;
|
||||
}
|
||||
else {
|
||||
// Rollover?
|
||||
if((ext->rollover) && (ext->value == ext->range_min))
|
||||
ext->value = ext->range_max;
|
||||
else
|
||||
ext->value = ext->range_min;
|
||||
}
|
||||
|
||||
lv_spinbox_updatevalue(spinbox);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the spinbox
|
||||
* @param spinbox pointer to a spinbox object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * param)
|
||||
{
|
||||
|
||||
lv_res_t res = LV_RES_OK;
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_spinbox_get_style(spinbox, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(spinbox, sign, param);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
if(sign != LV_SIGNAL_CONTROL) {
|
||||
res = ancestor_signal(spinbox, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
lv_obj_type_t * buf = param;
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
|
||||
if(buf->type[i] == NULL) break;
|
||||
}
|
||||
buf->type[i] = "lv_spinbox";
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
/*If released with an ENCODER then move to the next digit*/
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
if(lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) {
|
||||
#if LV_USE_GROUP
|
||||
if(lv_group_get_editing(lv_obj_get_group(spinbox))) {
|
||||
if(ext->step > 1) {
|
||||
lv_spinbox_step_next(spinbox);
|
||||
}
|
||||
else {
|
||||
/*Restart from the MSB*/
|
||||
ext->step = 1;
|
||||
uint32_t i;
|
||||
for(i = 0; i < ext->digit_count; i++) {
|
||||
int32_t new_step = ext->step * 10;
|
||||
if(new_step >= ext->range_max) break;
|
||||
ext->step = new_step;
|
||||
}
|
||||
lv_spinbox_step_prev(spinbox);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/*The cursor has been positioned to a digit.
|
||||
* Set `step` accordingly*/
|
||||
const char * txt = lv_textarea_get_text(spinbox);
|
||||
size_t txt_len = strlen(txt);
|
||||
|
||||
if(txt[ext->ta.cursor.pos] == '.') {
|
||||
lv_textarea_cursor_left(spinbox);
|
||||
}
|
||||
else if(ext->ta.cursor.pos == (uint32_t)txt_len) {
|
||||
lv_textarea_set_cursor_pos(spinbox, txt_len - 1);
|
||||
}
|
||||
else if(ext->ta.cursor.pos == 0 && ext->range_min < 0) {
|
||||
lv_textarea_set_cursor_pos(spinbox, 1);
|
||||
}
|
||||
|
||||
size_t len = ext->digit_count - 1;
|
||||
uint16_t cp = ext->ta.cursor.pos;
|
||||
|
||||
if(ext->ta.cursor.pos > ext->dec_point_pos && ext->dec_point_pos != 0) cp--;
|
||||
uint32_t pos = len - cp;
|
||||
|
||||
if(ext->range_min < 0) pos++;
|
||||
|
||||
ext->step = 1;
|
||||
uint16_t i;
|
||||
for(i = 0; i < pos; i++) ext->step *= 10;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CONTROL) {
|
||||
#if LV_USE_GROUP
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
|
||||
uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/
|
||||
if(c == LV_KEY_RIGHT) {
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER)
|
||||
lv_spinbox_increment(spinbox);
|
||||
else
|
||||
lv_spinbox_step_next(spinbox);
|
||||
}
|
||||
else if(c == LV_KEY_LEFT) {
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER)
|
||||
lv_spinbox_decrement(spinbox);
|
||||
else
|
||||
lv_spinbox_step_prev(spinbox);
|
||||
}
|
||||
else if(c == LV_KEY_UP) {
|
||||
lv_spinbox_increment(spinbox);
|
||||
}
|
||||
else if(c == LV_KEY_DOWN) {
|
||||
lv_spinbox_decrement(spinbox);
|
||||
}
|
||||
else {
|
||||
lv_textarea_add_char(spinbox, c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style descriptor of a part of the object
|
||||
* @param page pointer the object
|
||||
* @param part the part from `lv_spinbox_part_t`. (LV_SPINBOX_PART_...)
|
||||
* @return pointer to the style descriptor of the specified part
|
||||
*/
|
||||
static lv_style_list_t * lv_spinbox_get_style(lv_obj_t * ta, uint8_t part)
|
||||
{
|
||||
LV_ASSERT_OBJ(ta, LV_OBJX_NAME);
|
||||
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(ta);
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_SPINBOX_PART_BG:
|
||||
style_dsc_p = &ta->style_list;
|
||||
break;
|
||||
case LV_SPINBOX_PART_CURSOR:
|
||||
style_dsc_p = &ext->ta.cursor.style;
|
||||
break;
|
||||
default:
|
||||
style_dsc_p = NULL;
|
||||
}
|
||||
|
||||
return style_dsc_p;
|
||||
}
|
||||
static void lv_spinbox_updatevalue(lv_obj_t * spinbox)
|
||||
{
|
||||
lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);
|
||||
|
||||
char buf[LV_SPINBOX_MAX_DIGIT_COUNT + 8];
|
||||
_lv_memset_00(buf, sizeof(buf));
|
||||
char * buf_p = buf;
|
||||
uint8_t cur_shift_left = 0;
|
||||
|
||||
if(ext->range_min < 0) { // hide sign if there are only positive values
|
||||
/*Add the sign*/
|
||||
(*buf_p) = ext->value >= 0 ? '+' : '-';
|
||||
buf_p++;
|
||||
}
|
||||
else {
|
||||
/*Cursor need shift to left*/
|
||||
cur_shift_left++;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
/*padding left*/
|
||||
for(i = 0; i < ext->digit_padding_left; i++) {
|
||||
(*buf_p) = ' ';
|
||||
buf_p++;
|
||||
}
|
||||
|
||||
char digits[64];
|
||||
/*Convert the numbers to string (the sign is already handled so always covert positive number)*/
|
||||
_lv_utils_num_to_str(ext->value < 0 ? -ext->value : ext->value, digits);
|
||||
|
||||
/*Add leading zeros*/
|
||||
int lz_cnt = ext->digit_count - (int)strlen(digits);
|
||||
if(lz_cnt > 0) {
|
||||
for(i = (uint16_t)strlen(digits); i >= 0; i--) {
|
||||
digits[i + lz_cnt] = digits[i];
|
||||
}
|
||||
for(i = 0; i < lz_cnt; i++) {
|
||||
digits[i] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
int32_t intDigits;
|
||||
intDigits = (ext->dec_point_pos == 0) ? ext->digit_count : ext->dec_point_pos;
|
||||
|
||||
/*Add the decimal part*/
|
||||
for(i = 0; i < intDigits && digits[i] != '\0'; i++) {
|
||||
(*buf_p) = digits[i];
|
||||
buf_p++;
|
||||
}
|
||||
|
||||
if(ext->dec_point_pos != 0) {
|
||||
/*Insert the decimal point*/
|
||||
(*buf_p) = '.';
|
||||
buf_p++;
|
||||
|
||||
for(/*Leave i*/; i < ext->digit_count && digits[i] != '\0'; i++) {
|
||||
(*buf_p) = digits[i];
|
||||
buf_p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*Refresh the text*/
|
||||
lv_textarea_set_text(spinbox, (char *)buf);
|
||||
|
||||
/*Set the cursor position*/
|
||||
int32_t step = ext->step;
|
||||
uint8_t cur_pos = (uint8_t)ext->digit_count;
|
||||
while(step >= 10) {
|
||||
step /= 10;
|
||||
cur_pos--;
|
||||
}
|
||||
|
||||
if(cur_pos > intDigits) cur_pos++; /*Skip the decimal point*/
|
||||
|
||||
cur_pos += (ext->digit_padding_left - cur_shift_left);
|
||||
|
||||
lv_textarea_set_cursor_pos(spinbox, cur_pos);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
/**
|
||||
* @file lv_spinbox.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_SPINBOX_H
|
||||
#define LV_SPINBOX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_SPINBOX != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_TEXTAREA == 0
|
||||
#error "lv_spinbox: lv_ta is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_widgets/lv_textarea.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_SPINBOX_MAX_DIGIT_COUNT 10
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Data of spinbox*/
|
||||
typedef struct {
|
||||
lv_textarea_ext_t ta; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
int32_t value;
|
||||
int32_t range_max;
|
||||
int32_t range_min;
|
||||
int32_t step;
|
||||
uint8_t rollover : 1; // Set to true for rollover functionality
|
||||
uint16_t digit_count : 4;
|
||||
uint16_t dec_point_pos : 4; /*if 0, there is no separator and the number is an integer*/
|
||||
uint16_t digit_padding_left : 4;
|
||||
} lv_spinbox_ext_t;
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_SPINBOX_PART_BG = LV_TEXTAREA_PART_BG,
|
||||
LV_SPINBOX_PART_CURSOR = LV_TEXTAREA_PART_CURSOR,
|
||||
_LV_SPINBOX_PART_VIRTUAL_LAST = _LV_TEXTAREA_PART_VIRTUAL_LAST,
|
||||
_LV_SPINBOX_PART_REAL_LAST = _LV_TEXTAREA_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_spinbox_part_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a spinbox objects
|
||||
* @param par pointer to an object, it will be the parent of the new spinbox
|
||||
* @param copy pointer to a spinbox object, if not NULL then the new object will be copied from it
|
||||
* @return pointer to the created spinbox
|
||||
*/
|
||||
lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set spinbox rollover function
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param b true or false to enable or disable (default)
|
||||
*/
|
||||
void lv_spinbox_set_rollover(lv_obj_t * spinbox, bool b);
|
||||
|
||||
/**
|
||||
* Set spinbox value
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param i value to be set
|
||||
*/
|
||||
void lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i);
|
||||
|
||||
/**
|
||||
* Set spinbox digit format (digit count and decimal format)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param digit_count number of digit excluding the decimal separator and the sign
|
||||
* @param separator_position number of digit before the decimal point. If 0, decimal point is not
|
||||
* shown
|
||||
*/
|
||||
void lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_t separator_position);
|
||||
|
||||
/**
|
||||
* Set spinbox step
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param step steps on increment/decrement
|
||||
*/
|
||||
void lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step);
|
||||
|
||||
/**
|
||||
* Set spinbox value range
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param range_min maximum value, inclusive
|
||||
* @param range_max minimum value, inclusive
|
||||
*/
|
||||
void lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_max);
|
||||
|
||||
/**
|
||||
* Set spinbox left padding in digits count (added between sign and first digit)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param cb Callback function called on value change event
|
||||
*/
|
||||
void lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get spinbox rollover function status
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
bool lv_spinbox_get_rollover(lv_obj_t * spinbox);
|
||||
|
||||
/**
|
||||
* Get the spinbox numeral value (user has to convert to float according to its digit format)
|
||||
* @param spinbox pointer to spinbox
|
||||
* @return value integer value of the spinbox
|
||||
*/
|
||||
int32_t lv_spinbox_get_value(lv_obj_t * spinbox);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Select next lower digit for edition by dividing the step by 10
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_step_next(lv_obj_t * spinbox);
|
||||
|
||||
/**
|
||||
* Select next higher digit for edition by multiplying the step by 10
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_step_prev(lv_obj_t * spinbox);
|
||||
|
||||
/**
|
||||
* Increment spinbox value by one step
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_increment(lv_obj_t * spinbox);
|
||||
|
||||
/**
|
||||
* Decrement spinbox value by one step
|
||||
* @param spinbox pointer to spinbox
|
||||
*/
|
||||
void lv_spinbox_decrement(lv_obj_t * spinbox);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_SPINBOX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_SPINBOX_H*/
|
||||
@@ -1,326 +0,0 @@
|
||||
/**
|
||||
* @file lv_spinner.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_spinner.h"
|
||||
#if LV_USE_SPINNER != 0
|
||||
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_draw/lv_draw_rect.h"
|
||||
#include "../lv_draw/lv_draw_arc.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_OBJX_NAME "lv_spinner"
|
||||
|
||||
#ifndef LV_SPINNER_DEF_ARC_LENGTH
|
||||
#define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
#endif
|
||||
|
||||
#ifndef LV_SPINNER_DEF_SPIN_TIME
|
||||
#define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
#endif
|
||||
|
||||
#ifndef LV_SPINNER_DEF_ANIM
|
||||
#define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC /*animation type*/
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_spinner_signal(lv_obj_t * spinner, lv_signal_t sign, void * param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_signal_cb_t ancestor_signal;
|
||||
static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a spinner object
|
||||
* @param par pointer to an object, it will be the parent of the new spinner
|
||||
* @param copy pointer to a spinner object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created spinner
|
||||
*/
|
||||
lv_obj_t * lv_spinner_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("spinner create started");
|
||||
|
||||
/*Create the ancestor of spinner*/
|
||||
lv_obj_t * spinner = lv_arc_create(par, copy);
|
||||
LV_ASSERT_MEM(spinner);
|
||||
if(spinner == NULL) return NULL;
|
||||
|
||||
/*Allocate the spinner type specific extended data*/
|
||||
lv_spinner_ext_t * ext = lv_obj_allocate_ext_attr(spinner, sizeof(lv_spinner_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(spinner);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(spinner);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(spinner);
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
ext->arc_length = LV_SPINNER_DEF_ARC_LENGTH;
|
||||
ext->anim_type = LV_SPINNER_DEF_ANIM;
|
||||
ext->anim_dir = LV_SPINNER_DIR_FORWARD;
|
||||
ext->time = LV_SPINNER_DEF_SPIN_TIME;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(spinner, lv_spinner_signal);
|
||||
|
||||
/*Init the new spinner spinner*/
|
||||
if(copy == NULL) {
|
||||
ext->arc.bg_angle_start = 0;
|
||||
ext->arc.bg_angle_end = 360;
|
||||
lv_obj_set_size(spinner, LV_DPI, LV_DPI);
|
||||
lv_theme_apply(spinner, LV_THEME_SPINNER);
|
||||
|
||||
}
|
||||
/*Copy an existing spinner*/
|
||||
else {
|
||||
lv_spinner_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
ext->arc_length = copy_ext->arc_length;
|
||||
ext->time = copy_ext->time;
|
||||
ext->anim_dir = copy_ext->anim_dir;
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(spinner, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
lv_spinner_set_type(spinner, ext->anim_type);
|
||||
|
||||
LV_LOG_INFO("spinner created");
|
||||
|
||||
return spinner;
|
||||
}
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/**
|
||||
* Set the length of the spinning arc in degrees
|
||||
* @param spinner pointer to a spinner object
|
||||
* @param deg length of the arc
|
||||
*/
|
||||
void lv_spinner_set_arc_length(lv_obj_t * spinner, lv_anim_value_t deg)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
|
||||
ext->arc_length = deg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the spin time of the arc
|
||||
* @param spinner pointer to a spinner object
|
||||
* @param time time of one round in milliseconds
|
||||
*/
|
||||
void lv_spinner_set_spin_time(lv_obj_t * spinner, uint16_t time)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
|
||||
ext->time = time;
|
||||
lv_spinner_set_type(spinner, ext->anim_type);
|
||||
}
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the animation type of a spinner.
|
||||
* @param spinner pointer to spinner object
|
||||
* @param type animation type of the spinner
|
||||
* */
|
||||
void lv_spinner_set_type(lv_obj_t * spinner, lv_spinner_type_t type)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
|
||||
/*delete previous animation*/
|
||||
lv_anim_del(spinner, NULL);
|
||||
switch(type) {
|
||||
case LV_SPINNER_TYPE_FILLSPIN_ARC: {
|
||||
ext->anim_type = LV_SPINNER_TYPE_FILLSPIN_ARC;
|
||||
lv_anim_path_t path;
|
||||
lv_anim_path_init(&path);
|
||||
lv_anim_path_set_cb(&path, lv_anim_path_ease_in_out);
|
||||
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, spinner);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_spinner_anim_cb);
|
||||
lv_anim_set_path(&a, &path);
|
||||
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
|
||||
lv_anim_set_time(&a, ext->time);
|
||||
if(ext->anim_dir == LV_SPINNER_DIR_FORWARD) lv_anim_set_values(&a, 0, 360);
|
||||
else lv_anim_set_values(&a, 360, 0);
|
||||
lv_anim_start(&a);
|
||||
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_spinner_set_arc_length);
|
||||
if(ext->anim_dir == LV_SPINNER_DIR_FORWARD) lv_anim_set_values(&a, ext->arc_length, 360 - ext->arc_length);
|
||||
else lv_anim_set_values(&a, 360 - ext->arc_length, ext->arc_length);
|
||||
|
||||
lv_anim_set_playback_time(&a, ext->time);
|
||||
lv_anim_start(&a);
|
||||
break;
|
||||
}
|
||||
case LV_SPINNER_TYPE_CONSTANT_ARC:
|
||||
case LV_SPINNER_TYPE_SPINNING_ARC:
|
||||
default: {
|
||||
ext->anim_type = type;
|
||||
|
||||
lv_anim_path_t path;
|
||||
lv_anim_path_init(&path);
|
||||
lv_anim_path_set_cb(&path, (LV_SPINNER_TYPE_CONSTANT_ARC == type ? lv_anim_path_linear : lv_anim_path_ease_in_out));
|
||||
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, spinner);
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_spinner_anim_cb);
|
||||
lv_anim_set_time(&a, ext->time);
|
||||
lv_anim_set_path(&a, &path);
|
||||
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
|
||||
if(ext->anim_dir == LV_SPINNER_DIR_FORWARD) lv_anim_set_values(&a, 0, 360);
|
||||
else lv_anim_set_values(&a, 360, 0);
|
||||
lv_anim_start(&a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lv_spinner_set_dir(lv_obj_t * spinner, lv_spinner_dir_t dir)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
|
||||
ext->anim_dir = dir;
|
||||
lv_spinner_set_type(spinner, ext->anim_type);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the arc length [degree] of the a spinner
|
||||
* @param spinner pointer to a spinner object
|
||||
*/
|
||||
lv_anim_value_t lv_spinner_get_arc_length(const lv_obj_t * spinner)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
return ext->arc_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spin time of the arc
|
||||
* @param spinner pointer to a spinner object [milliseconds]
|
||||
*/
|
||||
uint16_t lv_spinner_get_spin_time(const lv_obj_t * spinner)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
return ext->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the animation type of a spinner.
|
||||
* @param spinner pointer to spinner object
|
||||
* @return animation type
|
||||
* */
|
||||
lv_spinner_type_t lv_spinner_get_type(lv_obj_t * spinner)
|
||||
{
|
||||
LV_ASSERT_OBJ(spinner, LV_OBJX_NAME);
|
||||
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
return ext->anim_type;
|
||||
}
|
||||
|
||||
lv_spinner_dir_t lv_spinner_get_dir(lv_obj_t * spinner)
|
||||
{
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
return ext->anim_dir;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Animator function (exec_cb) to rotate the arc of spinner.
|
||||
* @param ptr pointer to spinner
|
||||
* @param val the current desired value [0..360]
|
||||
*/
|
||||
void lv_spinner_anim_cb(void * ptr, lv_anim_value_t val)
|
||||
{
|
||||
lv_obj_t * spinner = ptr;
|
||||
lv_spinner_ext_t * ext = lv_obj_get_ext_attr(spinner);
|
||||
|
||||
int16_t angle_start = val - ext->arc_length / 2 - 90;
|
||||
if(angle_start < 0) angle_start += 360;
|
||||
int16_t angle_end = angle_start + ext->arc_length;
|
||||
|
||||
angle_start = angle_start % 360;
|
||||
angle_end = angle_end % 360;
|
||||
|
||||
lv_arc_set_angles(spinner, angle_start, angle_end);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Signal function of the spinner
|
||||
* @param spinner pointer to a spinner object
|
||||
* @param sign a signal type from lv_signal_t enum
|
||||
* @param param pointer to a signal specific variable
|
||||
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
|
||||
*/
|
||||
static lv_res_t lv_spinner_signal(lv_obj_t * spinner, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(spinner, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,180 +0,0 @@
|
||||
/**
|
||||
* @file lv_spinner.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_SPINNER_H
|
||||
#define LV_SPINNER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_SPINNER != 0
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_ARC == 0
|
||||
#error "lv_spinner: lv_arc is required. Enable it in lv_conf.h (LV_USE_ARC 1) "
|
||||
#endif
|
||||
|
||||
#if LV_USE_ANIMATION == 0
|
||||
#error "lv_spinner: animations are required. Enable it in lv_conf.h (LV_USE_ANIMATION 1) "
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "lv_arc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Type of spinner.
|
||||
*/
|
||||
enum {
|
||||
LV_SPINNER_TYPE_SPINNING_ARC,
|
||||
LV_SPINNER_TYPE_FILLSPIN_ARC,
|
||||
LV_SPINNER_TYPE_CONSTANT_ARC,
|
||||
};
|
||||
typedef uint8_t lv_spinner_type_t;
|
||||
|
||||
/**
|
||||
* Direction the spinner should spin.
|
||||
*/
|
||||
enum {
|
||||
LV_SPINNER_DIR_FORWARD,
|
||||
LV_SPINNER_DIR_BACKWARD,
|
||||
};
|
||||
typedef uint8_t lv_spinner_dir_t;
|
||||
|
||||
/*Data of spinner*/
|
||||
typedef struct {
|
||||
lv_arc_ext_t arc; /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
lv_anim_value_t arc_length; /*Length of the spinning indicator in degree*/
|
||||
uint16_t time; /*Time of one round*/
|
||||
lv_spinner_type_t anim_type : 2; /*Type of the arc animation*/
|
||||
lv_spinner_dir_t anim_dir : 1; /*Animation Direction*/
|
||||
} lv_spinner_ext_t;
|
||||
|
||||
/*Parts of the spinner*/
|
||||
enum {
|
||||
LV_SPINNER_PART_BG = LV_ARC_PART_BG,
|
||||
LV_SPINNER_PART_INDIC = LV_ARC_PART_INDIC,
|
||||
_LV_SPINNER_PART_VIRTUAL_LAST,
|
||||
|
||||
_LV_SPINNER_PART_REAL_LAST = _LV_ARC_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_spinner_style_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a spinner object
|
||||
* @param par pointer to an object, it will be the parent of the new spinner
|
||||
* @param copy pointer to a spinner object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created spinner
|
||||
*/
|
||||
lv_obj_t * lv_spinner_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*======================
|
||||
* Add/remove functions
|
||||
*=====================*/
|
||||
|
||||
/**
|
||||
* Set the length of the spinning arc in degrees
|
||||
* @param spinner pointer to a spinner object
|
||||
* @param deg length of the arc
|
||||
*/
|
||||
void lv_spinner_set_arc_length(lv_obj_t * spinner, lv_anim_value_t deg);
|
||||
|
||||
/**
|
||||
* Set the spin time of the arc
|
||||
* @param spinner pointer to a spinner object
|
||||
* @param time time of one round in milliseconds
|
||||
*/
|
||||
void lv_spinner_set_spin_time(lv_obj_t * spinner, uint16_t time);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the animation type of a spinner.
|
||||
* @param spinner pointer to spinner object
|
||||
* @param type animation type of the spinner
|
||||
* */
|
||||
void lv_spinner_set_type(lv_obj_t * spinner, lv_spinner_type_t type);
|
||||
|
||||
/**
|
||||
* Set the animation direction of a spinner
|
||||
* @param spinner pointer to spinner object
|
||||
* @param direction animation direction of the spinner
|
||||
*/
|
||||
void lv_spinner_set_dir(lv_obj_t * spinner, lv_spinner_dir_t dir);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the arc length [degree] of the a spinner
|
||||
* @param spinner pointer to a spinner object
|
||||
*/
|
||||
lv_anim_value_t lv_spinner_get_arc_length(const lv_obj_t * spinner);
|
||||
|
||||
/**
|
||||
* Get the spin time of the arc
|
||||
* @param spinner pointer to a spinner object [milliseconds]
|
||||
*/
|
||||
uint16_t lv_spinner_get_spin_time(const lv_obj_t * spinner);
|
||||
|
||||
/**
|
||||
* Get the animation type of a spinner.
|
||||
* @param spinner pointer to spinner object
|
||||
* @return animation type
|
||||
* */
|
||||
lv_spinner_type_t lv_spinner_get_type(lv_obj_t * spinner);
|
||||
|
||||
/**
|
||||
* Get the animation direction of a spinner
|
||||
* @param spinner pointer to spinner object
|
||||
* @return animation direction
|
||||
*/
|
||||
lv_spinner_dir_t lv_spinner_get_dir(lv_obj_t * spinner);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Animator function (exec_cb) to rotate the arc of spinner.
|
||||
* @param ptr pointer to spinner
|
||||
* @param val the current desired value [0..360]
|
||||
*/
|
||||
void lv_spinner_anim_cb(void * ptr, lv_anim_value_t val);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_SPINNER*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_SPINNER_H*/
|
||||
@@ -55,16 +55,17 @@ static lv_design_cb_t ancestor_design;
|
||||
|
||||
/**
|
||||
* Create a switch objects
|
||||
* @param par pointer to an object, it will be the parent of the new switch
|
||||
* @param copy pointer to a switch object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new switch
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other switch to copy.
|
||||
* @return pointer to the created switch
|
||||
*/
|
||||
lv_obj_t * lv_switch_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy)
|
||||
{
|
||||
LV_LOG_TRACE("switch create started");
|
||||
|
||||
/*Create the ancestor of switch*/
|
||||
lv_obj_t * sw = lv_bar_create(par, copy);
|
||||
lv_obj_t * sw = lv_bar_create(parent, copy);
|
||||
LV_ASSERT_MEM(sw);
|
||||
|
||||
if(sw == NULL) return NULL;
|
||||
@@ -88,21 +89,17 @@ lv_obj_t * lv_switch_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new switch switch*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_click(sw, true);
|
||||
lv_obj_add_protect(sw, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_add_flag(sw, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_size(sw, LV_DPX(60), LV_DPX(35));
|
||||
lv_bar_set_range(sw, 0, 1);
|
||||
|
||||
lv_theme_apply(sw, LV_THEME_SWITCH);
|
||||
}
|
||||
/*Copy an existing switch*/
|
||||
else {
|
||||
} else {
|
||||
lv_switch_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
|
||||
|
||||
lv_style_list_copy(&ext->style_knob, ©_ext->style_knob);
|
||||
lv_obj_refresh_style(sw, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
_lv_obj_refresh_style(sw, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
|
||||
LV_LOG_INFO("switch created");
|
||||
@@ -212,8 +209,8 @@ static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_ar
|
||||
lv_coord_t knob_size = objh;
|
||||
lv_area_t knob_area;
|
||||
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(sw, LV_SWITCH_PART_BG);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(sw, LV_SWITCH_PART_BG);
|
||||
lv_style_int_t bg_left = lv_obj_get_style_pad_left(sw, LV_SWITCH_PART_MAIN);
|
||||
lv_style_int_t bg_right = lv_obj_get_style_pad_right(sw, LV_SWITCH_PART_MAIN);
|
||||
|
||||
lv_coord_t max_indic_w = objw - bg_left - bg_right;
|
||||
lv_coord_t act_indic_w = lv_area_get_width(&ext->bar.indic_area);
|
||||
@@ -267,25 +264,23 @@ static lv_res_t lv_switch_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
|
||||
{
|
||||
lv_res_t res;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(sw, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_GET_STYLE) {
|
||||
lv_get_style_info_t * info = param;
|
||||
info->result = lv_switch_get_style(sw, info->part);
|
||||
if(info->result != NULL) return LV_RES_OK;
|
||||
else return ancestor_signal(sw, sign, param);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
res = ancestor_signal(sw, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
|
||||
}
|
||||
|
||||
/* Include the ancient signal function */
|
||||
res = ancestor_signal(sw, sign, param);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
lv_obj_clean_style_list(sw, LV_SWITCH_PART_KNOB);
|
||||
else if(sign == LV_SIGNAL_CLEANUP) {
|
||||
_lv_obj_reset_style_list_no_refr(sw, LV_SWITCH_PART_KNOB);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_switch_get_state(sw)) lv_switch_off(sw, LV_ANIM_ON);
|
||||
@@ -316,10 +311,11 @@ static lv_res_t lv_switch_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
|
||||
knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top));
|
||||
knob_size += 2; /*For rounding error*/
|
||||
|
||||
knob_size += lv_obj_get_draw_rect_ext_pad_size(sw, LV_SWITCH_PART_KNOB);
|
||||
knob_size += _lv_obj_get_draw_rect_ext_pad_size(sw, LV_SWITCH_PART_KNOB);
|
||||
|
||||
/*Indic. size is handled by bar*/
|
||||
sw->ext_draw_pad = LV_MATH_MAX(sw->ext_draw_pad, knob_size);
|
||||
lv_coord_t * s = param;
|
||||
*s = LV_MATH_MAX(*s, knob_size);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
#if LV_USE_GROUP
|
||||
@@ -339,7 +335,7 @@ static lv_style_list_t * lv_switch_get_style(lv_obj_t * sw, uint8_t part)
|
||||
lv_style_list_t * style_dsc_p;
|
||||
|
||||
switch(part) {
|
||||
case LV_SWITCH_PART_BG:
|
||||
case LV_SWITCH_PART_MAIN:
|
||||
style_dsc_p = &sw->style_list;
|
||||
break;
|
||||
case LV_SWITCH_PART_INDIC:
|
||||
|
||||
@@ -19,10 +19,9 @@ extern "C" {
|
||||
|
||||
/*Testing of dependencies*/
|
||||
#if LV_USE_SLIDER == 0
|
||||
#error "lv_sw: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER 1)"
|
||||
#error "lv_switch: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER 1)"
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "lv_bar.h"
|
||||
|
||||
/*********************
|
||||
@@ -43,7 +42,7 @@ typedef struct {
|
||||
* Switch parts.
|
||||
*/
|
||||
enum {
|
||||
LV_SWITCH_PART_BG = LV_BAR_PART_BG, /**< Switch background. */
|
||||
LV_SWITCH_PART_MAIN = LV_BAR_PART_MAIN, /**< Switch background. */
|
||||
LV_SWITCH_PART_INDIC = LV_BAR_PART_INDIC, /**< Switch fill area. */
|
||||
LV_SWITCH_PART_KNOB = _LV_BAR_PART_VIRTUAL_LAST, /**< Switch knob. */
|
||||
_LV_SWITCH_PART_VIRTUAL_LAST
|
||||
@@ -57,11 +56,12 @@ typedef uint8_t lv_switch_part_t;
|
||||
|
||||
/**
|
||||
* Create a switch objects
|
||||
* @param par pointer to an object, it will be the parent of the new switch
|
||||
* @param copy pointer to a switch object, if not NULL then the new object will be copied from it
|
||||
* @param parent pointer to an object, it will be the parent of the new switch
|
||||
* @param copy DEPRECATED, will be removed in v9.
|
||||
* Pointer to an other switch to copy.
|
||||
* @return pointer to the created switch
|
||||
*/
|
||||
lv_obj_t * lv_switch_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user