1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

refectoring and restructoring

This commit is contained in:
Gabor Kiss-Vamosi 2021-01-26 14:12:35 +01:00
parent c899595bff
commit 07268829c4
38 changed files with 1687 additions and 2280 deletions

View File

@ -201,7 +201,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
lv_disp_load_scr(d->scr_to_load);
lv_anim_del(d->scr_to_load, NULL);
lv_obj_set_pos(d->scr_to_load, 0, 0);
lv_style_remove_prop(lv_obj_get_local_style(d->scr_to_load, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
// lv_style_remove_prop(lv_obj_get_local_style(d->scr_to_load, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
act_scr = d->scr_to_load;
}
@ -222,8 +222,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_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
lv_style_remove_prop(lv_obj_get_local_style(lv_scr_act(), LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
// lv_style_remove_prop(lv_obj_get_local_style(new_scr, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
// lv_style_remove_prop(lv_obj_get_local_style(lv_scr_act(), LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
lv_anim_t a_new;
lv_anim_init(&a_new);
@ -396,6 +396,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;
d->scr_to_load = NULL;
lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
// lv_style_remove_prop(lv_obj_get_local_style(a->var, LV_PART_MAIN, LV_STATE_DEFAULT), LV_STYLE_OPA);
}
#endif

View File

@ -226,7 +226,7 @@ uint32_t lv_indev_get_key(const lv_indev_t * indev)
return indev->proc.types.keypad.last_key;
}
lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev)
lv_indev_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;
@ -815,7 +815,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
proc->long_pr_sent = 0;
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.scroll_dir = LV_INDEV_SCROLL_DIR_NONE;
proc->types.pointer.gesture_sent = 0;
proc->types.pointer.gesture_sum.x = 0;
proc->types.pointer.gesture_sum.y = 0;
@ -963,7 +963,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
indev->proc.longpr_rep_timestamp = 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_dir = LV_INDEV_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;
@ -980,7 +980,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
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);
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

View File

@ -121,7 +121,7 @@ uint32_t lv_indev_get_key(const lv_indev_t * indev);
* @return LV_SCROLL_DIR_NONE: no scrolling now
* LV_SCROLL_DIR_HOR/VER
*/
lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev);
lv_indev_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev);
/**
* Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and

View File

@ -71,7 +71,7 @@ void lv_indev_scroll_handler(lv_indev_proc_t * proc)
lv_coord_t diff_x = 0;
lv_coord_t diff_y = 0;
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) {
if(proc->types.pointer.scroll_dir == LV_INDEV_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);
@ -105,7 +105,7 @@ void lv_indev_scroll_throw_handler(lv_indev_proc_t * proc)
{
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
if(scroll_obj == NULL) return;
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) return;
if(proc->types.pointer.scroll_dir == LV_INDEV_SCROLL_DIR_NONE) return;
lv_indev_t * indev_act = lv_indev_get_act();
@ -119,7 +119,7 @@ void lv_indev_scroll_throw_handler(lv_indev_proc_t * proc)
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) {
if(proc->types.pointer.scroll_dir == LV_INDEV_SCROLL_DIR_VER) {
proc->types.pointer.scroll_throw_vect.x = 0;
/*If no snapping "throw"*/
if(align_y == LV_SCROLL_SNAP_ALIGN_NONE) {
@ -142,7 +142,7 @@ void lv_indev_scroll_throw_handler(lv_indev_proc_t * proc)
lv_obj_scroll_by(scroll_obj, 0, diff_y + y, LV_ANIM_ON);
}
}
else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) {
else if(proc->types.pointer.scroll_dir == LV_INDEV_SCROLL_DIR_HOR) {
proc->types.pointer.scroll_throw_vect.y = 0;
/*If no snapping "throw"*/
if(align_x == LV_SCROLL_SNAP_ALIGN_NONE) {
@ -202,7 +202,7 @@ void lv_indev_scroll_throw_handler(lv_indev_proc_t * proc)
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_dir = LV_INDEV_SCROLL_DIR_NONE;
proc->types.pointer.scroll_obj = NULL;
}
}
@ -303,7 +303,7 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)))
{
obj_candidate = obj_act;
dir_candidate = LV_SCROLL_DIR_VER;
dir_candidate = LV_INDEV_SCROLL_DIR_VER;
}
if((sl > 0 || sr > 0) &&
@ -311,7 +311,7 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit)))
{
obj_candidate = obj_act;
dir_candidate = LV_SCROLL_DIR_HOR;
dir_candidate = LV_INDEV_SCROLL_DIR_HOR;
}
if(st <= 0) up_en = false;
@ -325,7 +325,7 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
(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;
proc->types.pointer.scroll_dir = hor_en ? LV_INDEV_SCROLL_DIR_HOR : LV_INDEV_SCROLL_DIR_VER;
break;
}
@ -351,7 +351,7 @@ 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) {
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ONE) == false) {
lv_area_set(&proc->types.pointer.scroll_area, LV_COORD_MIN, LV_COORD_MIN, LV_COORD_MAX, LV_COORD_MAX);
}
/*With STOP limit the scrolling to the perv and next snap point*/

File diff suppressed because it is too large Load Diff

View File

@ -22,12 +22,7 @@ extern "C" {
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_debug.h"
#include "../lv_misc/lv_class.h"
#include "../lv_hal/lv_hal.h"
#include "../lv_draw/lv_draw_rect.h"
#include "../lv_draw/lv_draw_label.h"
#include "../lv_draw/lv_draw_line.h"
#include "../lv_draw/lv_draw_img.h"
/*********************
* DEFINES
@ -42,12 +37,13 @@ extern "C" {
#error "LVGL: LV_ANTIALIAS can be only 0 or 1"
#endif
#define LV_MAX_ANCESTOR_NUM 8
#define _LV_OBJ_PART_MAX 32
#define LV_EXT_CLICK_AREA_OFF 0
#define LV_EXT_CLICK_AREA_TINY 1
#define LV_EXT_CLICK_AREA_FULL 2
/**
* Options for extra click area behavior.
* These values can be selected in `lv_conf.h`
*/
#define LV_EXT_CLICK_AREA_OFF 0 /*Disable the usage of extra click area*/
#define LV_EXT_CLICK_AREA_TINY 1 /*Use the same value in all 4 directions*/
#define LV_EXT_CLICK_AREA_FULL 2 /*Allow setting different values in every 4 directions*/
/**********************
* TYPEDEFS
@ -55,8 +51,14 @@ extern "C" {
struct _lv_obj_t;
/*---------------------
* EVENTS
*---------------------*/
enum {
/**
* Type of event being sent to the object.
*/
typedef enum {
LV_EVENT_PRESSED, /**< The object has been pressed*/
LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/
LV_EVENT_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */
@ -77,8 +79,6 @@ enum {
LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved) */
LV_EVENT_INSERT,
LV_EVENT_REFRESH,
LV_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/
LV_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/
LV_EVENT_DELETE, /**< Object is being deleted */
LV_EVENT_COVER_CHECK, /**< Check if the object fully covers the 'mask_p' area */
@ -91,9 +91,8 @@ enum {
LV_EVENT_DRAW_PART_BEGIN,
LV_EVENT_DRAW_PART_END,
_LV_EVENT_LAST /** Number of events*/
};
typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */
_LV_EVENT_LAST /** Number of default events*/
}lv_event_t;
/**
* @brief Event callback.
@ -102,10 +101,17 @@ typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */
*/
typedef void (*lv_event_cb_t)(struct _lv_obj_t * obj, lv_event_t event);
/*---------------------
* EVENTS
*---------------------*/
/** Signals are for use by the object itself or to extend the object's functionality.
* They determine a widget with a given type should behave.
* Applications should use ::lv_obj_set_event_cb to be notified of events that occur
* on the object. */
enum {
typedef enum {
/*General signals*/
LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */
LV_SIGNAL_COORD_CHG, /**< Object coordinates/size have changed */
@ -127,54 +133,93 @@ enum {
LV_SIGNAL_SCROLL_END, /**< The scrolling has ended */
LV_SIGNAL_GESTURE, /**< The object has been gesture*/
LV_SIGNAL_LEAVE, /**< Another object is clicked or chosen via an input device */
LV_SIGNAL_FOCUS, /**< The object was focused */
LV_SIGNAL_DEFOCUS, /**< The object was de-focused */
LV_SIGNAL_CONTROL, /**< Send a (control) character to the widget */
} lv_signal_t;
/*Group related*/
LV_SIGNAL_FOCUS,
LV_SIGNAL_DEFOCUS,
LV_SIGNAL_CONTROL,
LV_SIGNAL_GET_EDITABLE,
};
typedef uint8_t lv_signal_t;
/**
* @brief Signal callback.
* Signals are used to notify the widget of the action related to the object.
* For details, see ::lv_signal_t.
*/
typedef lv_res_t (*lv_signal_cb_t)(struct _lv_obj_t * obj, lv_signal_t sign, void * param);
/**
* Possible states of a widget.
* OR-ed values are possible
*/
enum {
LV_STATE_DEFAULT = 0x00,
LV_STATE_CHECKED = 0x01,
LV_STATE_FOCUSED = 0x02,
LV_STATE_EDITED = 0x04,
LV_STATE_HOVERED = 0x08,
LV_STATE_PRESSED = 0x10,
LV_STATE_SCROLLED = 0x20,
LV_STATE_DISABLED = 0x40,
LV_STATE_USER = 0x80, /** Free to use by the user */
LV_STATE_KEY_FOCUSED = 0x04,
LV_STATE_EDITED = 0x08,
LV_STATE_HOVERED = 0x10,
LV_STATE_PRESSED = 0x20,
LV_STATE_SCROLLED = 0x40,
LV_STATE_DISABLED = 0x80,
LV_STATE_ANY = 0x1FF, /**< Special value can be used in some functions to target all states */
};
typedef uint8_t lv_state_t;
typedef uint16_t lv_state_t;
/**
* The possible parts of widgets.
* The parts can be considered as the internal building block of the widgets.
* E.g. slider = background + indicator + knob
* Note every part is used by every widget
*/
enum {
LV_OBJ_FLAG_HIDDEN = (1 << 0),
LV_OBJ_FLAG_CLICKABLE = (1 << 1),
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1 << 2),
LV_OBJ_FLAG_CHECKABLE = (1 << 3),
LV_OBJ_FLAG_SCROLLABLE = (1 << 4),
LV_OBJ_FLAG_SCROLL_ELASTIC = (1 << 5),
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1 << 6),
LV_OBJ_FLAG_SCROLL_STOP = (1 << 7),
LV_OBJ_FLAG_SCROLL_CHAIN = (1 << 8), /** Allow propagating the scroll to a parent */
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1 << 9), /** Automatically scroll the focused object's ancestors to make the focused object visible*/
LV_OBJ_FLAG_SNAPABLE = (1 << 10),
LV_OBJ_FLAG_PRESS_LOCK = (1 << 11),
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 12),
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 13),
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 14),
LV_OBJ_FLAG_ADV_HITTEST = (1 << 15),
LV_OBJ_FLAG_LAYOUTABLE = (1 << 16),
LV_PART_MAIN, /**< A background like rectangle*/
LV_PART_SCROLLBAR, /**< The scrollbar(s)*/
LV_PART_INDICATOR, /**< Indicator, e.g. for slider, bar, switch, */
LV_PART_KNOB, /**< Like handle to grab to adjust the value */
LV_PART_SELECTED, /**< Indicate the currently selected option or section*/
LV_PART_PLACEHOLDER, /**< A text other element used when the widget is empty*/
LV_PART_ITEMS, /**< Used if the widget has multiple similar elements (e.g. tabel cells)*/
LV_PART_MARKER, /**< Tick box of a check box, cursor of a text area or anything used to mark something*/
LV_PART_CUSTOM_1, /**< Extension point for custom widgets*/
LV_PART_CUSTOM_2, /**< Extension point for custom widgets*/
LV_PART_CUSTOM_3, /**< Extension point for custom widgets*/
LV_PART_CUSTOM_4, /**< Extension point for custom widgets*/
LV_PART_ANY = 0xFF, /**< Special value can be used in some functions to target all parts */
};
typedef uint16_t lv_part_t;
/**
* On/Off features controlling the object's behavior.
* OR-ed values are possible
*/
enum {
LV_OBJ_FLAG_HIDDEN = (1 << 0), /**< Make the object hidden. (Like it wasn't there at all) */
LV_OBJ_FLAG_CLICKABLE = (1 << 1), /**< Make the object clickable by the input devices */
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1 << 2), /**< Add focused state to the object when clicked */
LV_OBJ_FLAG_CHECKABLE = (1 << 3), /**< Toggle checked state when the object is clicked */
LV_OBJ_FLAG_SCROLLABLE = (1 << 4), /**< Make the object scrollable*/
LV_OBJ_FLAG_SCROLL_ELASTIC = (1 << 5), /**< Allow scrolling inside but with slower speed*/
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1 << 6), /**< Make the object scroll further when "thrown"*/
LV_OBJ_FLAG_SCROLL_ONE = (1 << 7), /**< Allow scrolling only one snappable children*/
LV_OBJ_FLAG_SCROLL_CHAIN = (1 << 8), /**< Allow propagating the scroll to a parent */
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1 << 9), /**< Automatically scroll object to make it visible when focused*/
LV_OBJ_FLAG_SNAPABLE = (1 << 10), /**< If scroll snap is enabled it can snap to this object*/
LV_OBJ_FLAG_PRESS_LOCK = (1 << 11), /**< Keep the object pressed even if the press slid from the object */
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 12), /**< Propagate the events to the parent too */
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 13), /**< Propagate the gestures to the parent */
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 14), /**< Propagate the focus to the parent */
LV_OBJ_FLAG_ADV_HITTEST = (1 << 15), /**< Allow performing more accurate hit (click) test. E.g. on rounded corners. */
LV_OBJ_FLAG_LAYOUTABLE = (1 << 16), /**< MAke the object position-able by the layouts */
LV_OBJ_FLAG_LAYOUT_1 = (1 << 24), /** Custom flag, free to use by layouts*/
LV_OBJ_FLAG_LAYOUT_2 = (1 << 25), /** Custom flag, free to use by layouts*/
LV_OBJ_FLAG_WIDGET_1 = (1 << 26), /** Custom flag, free to use by widget*/
LV_OBJ_FLAG_WIDGET_2 = (1 << 27), /** Custom flag, free to use by widget*/
LV_OBJ_FLAG_USER_1 = (1 << 28), /** Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_2 = (1 << 29), /** Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_3 = (1 << 30), /** Custom flag, free to use by user*/
@ -182,6 +227,7 @@ enum {
};
typedef uint32_t lv_obj_flag_t;
#include "lv_obj_tree.h"
#include "lv_obj_pos.h"
#include "lv_obj_scroll.h"
#include "lv_obj_style.h"
@ -189,45 +235,55 @@ typedef uint32_t lv_obj_flag_t;
#include "lv_grid.h"
#include "lv_flex.h"
/**
* Describe the common methods of every object.
* Similar to a C++ class.
*/
typedef struct _lv_obj_class_t{
const struct _lv_obj_class_t * base_class;
void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy);
void (*destructor)(struct _lv_obj_t * obj);
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/
lv_draw_cb_t draw_cb; /**< Object type specific draw function*/
uint32_t editable :1;
uint32_t instance_size :20;
}lv_obj_class_t;
/**
* Make the base object's class publicly available.
*/
extern const lv_obj_class_t lv_obj;
/**
* Special, rarely used attributes.
* They are allocated automatically if any elements is set.
*/
typedef struct {
struct _lv_obj_t ** children; /**< Store the pointer of the children.*/
uint32_t child_cnt;
struct _lv_obj_t ** children; /**< Store the pointer of the children in an array.*/
uint32_t child_cnt; /**< Number of children */
#if LV_USE_GROUP != 0
void * group_p;
#endif
const lv_layout_dsc_t * layout_dsc;
const lv_layout_dsc_t * layout_dsc; /**< Pointer to the layout descriptor*/
lv_event_cb_t event_cb; /**< Event callback function */
lv_point_t scroll; /**< The current X/Y scroll offset*/
lv_coord_t ext_draw_size; /**< EXTend the size in every direction for drawing. */
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
uint8_t ext_click_pad; /**< Extra click padding in all direction */
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_t ext_click_pad; /**< Extra click padding area. */
#endif
lv_coord_t ext_draw_size; /**< EXTend the size in every direction for drawing. */
lv_scrollbar_mode_t scrollbar_mode :2; /**< How to display scrollbars*/
lv_snap_align_t snap_align_x : 2;
lv_snap_align_t snap_align_y : 2;
lv_scroll_dir_t scroll_dir :4;
lv_snap_align_t snap_align_x : 2; /**< Where to align the snapable children horizontally*/
lv_snap_align_t snap_align_y : 2; /**< Where to align the snapable children horizontally*/
lv_dir_t scroll_dir :4; /**< The allowed scroll direction(s)*/
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
}lv_obj_spec_attr_t;
#define _lv_obj_constructor
typedef struct lv_obj_class{
const struct lv_obj_class * base_class;
void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy);
void (*destructor)(struct _lv_obj_t * obj);
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/
lv_draw_cb_t draw_cb; /**< Object type specific draw function*/
uint32_t instance_size;
}lv_obj_class_t;
typedef struct _lv_obj_t{
const lv_obj_class_t * class_p;
struct _lv_obj_t * parent;
@ -242,24 +298,9 @@ typedef struct _lv_obj_t{
lv_state_t state;
}lv_obj_t;
extern const lv_obj_class_t lv_obj;
enum {
LV_PART_MAIN,
LV_PART_SCROLLBAR,
LV_PART_INDICATOR,
LV_PART_KNOB,
LV_PART_HIGHLIGHT, //selected?
LV_PART_PLACEHOLDER,
LV_PART_ITEMS,
LV_PART_MARKER,
LV_PART_CURSOR, //combine with marker?
};
typedef uint8_t lv_part_t;
typedef struct {
lv_point_t * point;
const lv_point_t * point;
bool result;
} lv_hit_test_info_t;
@ -268,234 +309,44 @@ typedef struct {
**********************/
/**
* Init. the 'lv' library.
* Initialize LVGL library.
* Should be called before any other LVGL related function.
*/
void lv_init(void);
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
/**
* Deinit the 'lv' library
* Currently only implemented when not using custom allocators, or GC is enabled.
*/
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
void lv_deinit(void);
#endif
/*--------------------
* Create and delete
*-------------------*/
/**
* Create a basic object
* @param parent pointer to a parent object.
* If NULL then a screen will be created
*
* @param copy DEPRECATED, will be removed in v9.
* Create a base object (a rectangle)
* @param parent: pointer to a parent object. If NULL then a screen will be created.
* @param copy: DEPRECATED, will be removed in v9.
* Pointer to an other base object to copy.
* @return pointer to the new object
*/
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy);
lv_obj_t * lv_obj_create_from_class(const lv_obj_class_t * class, lv_obj_t * parent, const lv_obj_t * copy);
void lv_obj_construct_base(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
/**
* Delete 'obj' and all of its children
* @param obj pointer to an object to delete
* @return LV_RES_INV because the object is deleted
*/
lv_res_t lv_obj_del(lv_obj_t * obj);
#if LV_USE_ANIMATION
/**
* A function to be easily used in animation ready callback to delete an object when the animation is ready
* @param a pointer to the animation
*/
void lv_obj_del_anim_ready_cb(lv_anim_t * a);
#endif
/**
* Helper function for asynchronously deleting objects.
* Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).
* @param obj object to delete
* @see lv_async_call
*/
void lv_obj_del_async(struct _lv_obj_t * obj);
/**
* Delete all children of an object
* @param obj pointer to an object
*/
void lv_obj_clean(lv_obj_t * obj);
/**
* Mark an area of an object as invalid.
* This area will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
* @param area the area to redraw
*/
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
/**
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
*/
void lv_obj_invalidate(const lv_obj_t * obj);
/**
* Tell whether an area of an object is visible (even partially) now or not
* @param obj pointer to an object
* @param area the are to check. The visible part of the area will be written back here.
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
*/
bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area);
/**
* Tell whether an object is visible (even partially) now or not
* @param obj pointer to an object
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
*/
bool lv_obj_is_visible(const lv_obj_t * obj);
/*=====================
* Setter functions
*====================*/
/*--------------------
* Parent/children set
*--------------------*/
/**
* Set a new parent for an object. Its relative position will be the same.
* @param obj pointer to an object. Can't be a screen.
* @param parent pointer to the new parent object. (Can't be NULL)
*/
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent);
/**
* Move and object to the foreground
* @param obj pointer to an object
*/
void lv_obj_move_foreground(lv_obj_t * obj);
/**
* Move and object to the background
* @param obj pointer to an object
*/
void lv_obj_move_background(lv_obj_t * obj);
/*--------------------
* Coordinate set
* ------------------*/
/**
* Set the size of an extended clickable area
* @param obj pointer to an object
* @param left extended clickable are on the left [px]
* @param right extended clickable are on the right [px]
* @param top extended clickable are on the top [px]
* @param bottom extended clickable are on the bottom [px]
*/
void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom);
/**
* Get the extended draw area of an object.
* @param obj pointer to an object
* @return the size extended draw area around the real coordinates
*/
lv_coord_t _lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
/*---------------------
* Appearance set
*--------------------*/
/*-----------------
* Attribute set
*----------------*/
/**
* Set the base direction of the object
* @param obj pointer to an object
* @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT`
*/
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir);
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
/**
* Set the state (fully overwrite) of an object.
* If specified in the styles a transition animation will be started
* from the previous state to the current
* @param obj pointer to an object
* @param state the new state
*/
void lv_obj_set_state(lv_obj_t * obj, lv_state_t state);
/**
* Add a given state or states to the object. The other state bits will remain unchanged.
* If specified in the styles a transition animation will be started
* from the previous state to the current
* @param obj pointer to an object
* @param state the state bits to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
*/
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
/**
* Remove a given state or states to the object. The other state bits will remain unchanged.
* If specified in the styles a transition animation will be started
* from the previous state to the current
* @param obj pointer to an object
* @param state the state bits to remove. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
*/
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state);
/**
* Set a an event handler function for an object.
* Used by the user to react on event which happens with the object.
* @param obj pointer to an object
* @param event_cb the new event function
*/
void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);
* Event/Signal sending
*---------------------*/
/**
* Send an event to the object
* @param obj pointer to an object
* @param event the type of the event from `lv_event_t`.
* @param event the type of the event from `lv_event_t`
* @param data arbitrary data depending on the object type and the event. (Usually `NULL`)
* @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event
*/
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data);
/**
* Send LV_EVENT_REFRESH event to an object
* @param obj point to an object. (Can NOT be NULL)
* @return LV_RES_OK: success, LV_RES_INV: to object become invalid (e.g. deleted) due to this event.
*/
lv_res_t lv_event_send_refresh(lv_obj_t * obj);
/**
* Send LV_EVENT_REFRESH event to an object and all of its children
* @param obj pointer to an object or NULL to refresh all objects of all displays
*/
void lv_event_send_refresh_recursive(lv_obj_t * obj);
/**
* Call an event function with an object, event, and data.
* @param event_xcb an event callback function. If `NULL` `LV_RES_OK` will return without any actions.
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
* the `func_name(object, callback, ...)` convention)
* @param obj pointer to an object to associate with the event (can be `NULL` to simply call the `event_cb`)
* @param event an event
* @param data pointer to a custom data
* @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event
*/
lv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data);
/**
* Get the `data` parameter of the current event
* @return the `data` parameter
@ -510,133 +361,92 @@ void * lv_event_get_data(void);
*/
lv_res_t lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param);
/*----------------
* Other set
*--------------*/
/*=====================
* Setter functions
*====================*/
/**
* Allocate a new ext. data for an object
* @param obj pointer to an object
* @param ext_size the size of the new ext. data
* @return pointer to the allocated ext
* Set one or more flags
* @param obj: pointer to an object
* @param f: OR-ed values from `lv_obj_flag_t` to set.
*/
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
/**
* Clear one or more flags
* @param obj: pointer to an object
* @param f: OR-ed values from `lv_obj_flag_t` to set.
*/
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
/**
* Set the state (fully overwrite) of an object.
* If specified in the styles, transition animations will be started from the previous state to the current.
* @param obj: pointer to an object
* @param state: the new state
*/
void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state);
/**
* Add one or more states to the object. The other state bits will remain unchanged.
* If specified in the styles, transition animation will be started from the previous state to the current.
* @param obj: pointer to an object
* @param state: the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
*/
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
/**
* Remove one or more states to the object. The other state bits will remain unchanged.
* If specified in the styles, transition animation will be started from the previous state to the current.
* @param obj: pointer to an object
* @param state: the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
*/
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state);
/**
* Set a an event handler function for an object.
* Used by the user to react on event which happens with the object.
* @param obj pointer to an object
* @param event_cb the new event function
*/
void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);
/**
* Set the base direction of the object
* @param obj pointer to an object
* @param dir the new base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT`
*/
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir);
lv_obj_spec_attr_t * lv_obj_allocate_spec_attr(lv_obj_t * obj);
/*=======================
* Getter functions
*======================*/
/**
* Return with the screen of an object
* Check if a given flag or flags are set on an object.
* @param obj pointer to an object
* @return pointer to a screen
* @param f the flag(s) to check (OR-ed values can be used)
* @return true: all flags are set; false: not all flags are set
*/
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);
/**
* Get the display of an object
* @return pointer the object's display
*/
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);
/*---------------------
* Parent/children get
*--------------------*/
/**
* Returns with the parent of an object
* @param obj pointer to an object
* @return pointer to the parent of 'obj'
*/
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj);
/**
* Get the Nth child of a an object. 0th is the lastly created.
* @param obj pointer to an object whose children should be get
* @param id of a child
* @return the child or `NULL` if `id` was greater then the `number of children - 1`
*/
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, uint32_t id);
uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj);
/**
* Get the child index of an object.
* If this object is the firstly created child of its parent 0 will be return.
* If its the second child return 1, etc.
* @param obj pointer to an object whose index should be get
* @return the child index of the object.
*/
uint32_t lv_obj_get_child_id(const lv_obj_t * obj);
/**
* Count the children of an object (only children directly on 'obj')
* @param obj pointer to an object
* @return children number of 'obj'
*/
uint32_t lv_obj_count_children(const lv_obj_t * obj);
/** Recursively count the children of an object
* @param obj pointer to an object
* @return children number of 'obj'
*/
uint32_t lv_obj_count_children_recursive(const lv_obj_t * obj);
/*---------------------
* Coordinate get
*--------------------*/
/**
* Get the extended extended clickable area in a direction
* @param obj pointer to an object
* @param dir in which direction get the extended area (`LV_DIR_LEFT/RIGHT/TOP`)
* @return the extended left padding
*/
lv_coord_t lv_obj_get_ext_click_area(const lv_obj_t * obj, lv_dir_t dir);
/**
* Check if a given screen-space point is on an object's coordinates.
* This method is intended to be used mainly by advanced hit testing algorithms to check
* whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/
bool _lv_obj_is_click_point_on(lv_obj_t * obj, const lv_point_t * point);
/**
* Hit-test an object given a particular point in screen space.
* @param obj object to hit-test
* @param point screen-space point
* @return true if the object is considered under the point
*/
bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/*-----------------
* Attribute get
*----------------*/
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
/**
* Get the base direction of the object
* @param obj pointer to an object
* @return the base direction. `LV_BIDI_DIR_LTR/RTL/AUTO/INHERIT`
*/
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj);
/**
* Get the state of an object
* @param obj pointer to an object
* @return the state (OR-ed values from `lv_state_t`)
*/
lv_state_t lv_obj_get_state(const lv_obj_t * obj);
/**
* Get the signal function of an object
* @param obj pointer to an object
* @return the signal function
*/
lv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj);
/**
* Get the draw function of an object
* @param obj pointer to an object
* @return the draw function
*/
lv_draw_cb_t lv_obj_get_draw_cb(const lv_obj_t * obj);
/**
* Get the event function of an object
* @param obj pointer to an object
@ -644,52 +454,6 @@ lv_draw_cb_t lv_obj_get_draw_cb(const lv_obj_t * obj);
*/
lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj);
/*------------------
* Other get
*-----------------*/
/**
* Hit-test an object given a particular point in screen space.
* @param obj object to hit-test
* @param point screen-space point
* @return true if the object is considered under the point
*/
bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/**
* Get the ext pointer
* @param obj pointer to an object
* @return the ext pointer but not the dynamic version
* Use it as ext->data1, and NOT da(ext)->data1
*/
void * lv_obj_get_ext_attr(const lv_obj_t * obj);
bool lv_obj_check_type(const lv_obj_t * obj, const void * class_p);
#if LV_USE_USER_DATA
/**
* Get the object's user data
* @param obj pointer to an object
* @return user data
*/
lv_obj_user_data_t lv_obj_get_user_data(const lv_obj_t * obj);
/**
* Get a pointer to the object's user data
* @param obj pointer to an object
* @return pointer to the user data
*/
lv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj);
/**
* Set the object's user data. The data will be copied.
* @param obj pointer to an object
* @param data user data
*/
void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data);
#endif
/**
* Get the group of the object
* @param obj pointer to an object
@ -697,25 +461,30 @@ void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data);
*/
void * lv_obj_get_group(const lv_obj_t * obj);
/*=======================
* Other functions
*======================*/
/**
* Tell whether the object is the focused object of a group or not.
* Allocate special data for an object if not allocated yet.
* @param obj pointer to an object
* @return true: the object is focused, false: the object is not focused or not in a group
*/
bool lv_obj_is_focused(const lv_obj_t * obj);
lv_obj_t ** lv_obj_get_children(const lv_obj_t * obj);
void lv_obj_allocate_spec_attr(lv_obj_t * obj);
/**
* Get the really focused object by taking `focus_parent` into account.
* Get the focused object by taking `LV_OBJ_FLAG_FOCUS_BUBBLE` into account.
* @param obj the start object
* @return the object to really focus
* @return the object to to really focus
*/
lv_obj_t * _lv_obj_get_focused_obj(const lv_obj_t * obj);
lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj);
/*-------------------
* OTHER FUNCTIONS
*------------------*/
/**
* Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.
* E.g. buf.type[0]="lv_btn", buf.type[1]="lv_cont", buf.type[2]="lv_obj"
* @param obj pointer to an object which type should be get
* @param buf pointer to an `lv_obj_type_t` buffer to store the types
*/
bool lv_obj_check_type(const lv_obj_t * obj, const void * class_p);
/**
* Check if any object has a given type
@ -737,23 +506,6 @@ bool _lv_debug_check_obj_valid(const lv_obj_t * obj);
* MACROS
**********************/
/**
* Helps to quickly declare an event callback function.
* Will be expanded to: `static void <name> (lv_obj_t * obj, lv_event_t e)`
*
* Examples:
* LV_EVENT_CB_DECLARE(my_event1); //Prototype declaration
*
* LV_EVENT_CB_DECLARE(my_event1)
* {
* if(e == LV_EVENT_CLICKED) {
* lv_obj_set_hidden(obj ,true);
* }
* }
*/
#define LV_EVENT_CB_DECLARE(name) static void name(lv_obj_t * obj, lv_event_t e)
#if LV_USE_DEBUG
# ifndef LV_DEBUG_IS_OBJ

View File

@ -344,41 +344,41 @@ lv_coord_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint8_t part)
return s;
}
/**
* Initialize a draw hook.
* @param hook_dsc: pointer to a raw hook. Later it should be passed as parameter to an `LV_EEVNT_DRAW_PART_BEGIN/END` event.
* @param clip_area: the current clip area of the drawing
*/
void lv_obj_draw_hook_dsc_init(lv_obj_draw_hook_dsc_t * hook_dsc, const lv_area_t * clip_area)
{
lv_memset_00(hook_dsc, sizeof(lv_obj_draw_hook_dsc_t));
hook_dsc->clip_area = clip_area;
}
/**
* Send a 'LV_SIGNAL_REFR_EXT_DRAW_SIZE' signal to the object to refresh the value of the extended draw size.
* The result will be saved in `obj`.
* @param obj: pointer to an object
*/
void lv_obj_refresh_ext_draw_size(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t s = 0;
lv_signal_send(obj, LV_SIGNAL_REFR_EXT_DRAW_SIZE, &s);
lv_coord_t s_old = _lv_obj_get_ext_draw_size(obj);
lv_coord_t s_new = 0;
lv_signal_send(obj, LV_SIGNAL_REFR_EXT_DRAW_SIZE, &s_new);
if(s_new != s_old) lv_obj_invalidate(obj);
/*Store the result if the special attrs already allocated*/
if(obj->spec_attr) {
obj->spec_attr->ext_draw_size = s;
obj->spec_attr->ext_draw_size = s_new;
}
/* Allocate spec. attrs. only if the result is not zero.
* Zero is the default value if the spec. attr. are not defined. */
else if(s != 0) {
else if(s_new != 0) {
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->ext_draw_size = s;
}
obj->spec_attr->ext_draw_size = s_new;
}
if(s_new != s_old) lv_obj_invalidate(obj);
}
lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->ext_draw_size;
else return 0;
}
/**********************
* STATIC FUNCTIONS

View File

@ -141,6 +141,13 @@ void lv_obj_draw_hook_dsc_init(lv_obj_draw_hook_dsc_t * hook_dsc, const lv_area_
*/
void lv_obj_refresh_ext_draw_size(struct _lv_obj_t * obj);
/**
* Get the extended draw area of an object.
* @param obj pointer to an object
* @return the size extended draw area around the real coordinates
*/
lv_coord_t _lv_obj_get_ext_draw_size(const struct _lv_obj_t * obj);
/**********************
* MACROS
**********************/

View File

@ -593,6 +593,150 @@ void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_dif
}
}
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_area_t area_tmp;
lv_area_copy(&area_tmp, area);
bool visible = lv_obj_area_is_visible(obj, &area_tmp);
if(visible) _lv_inv_area(lv_obj_get_disp(obj), &area_tmp);
}
void lv_obj_invalidate(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/*Truncate the area to the object*/
lv_area_t obj_coords;
lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj);
lv_area_copy(&obj_coords, &obj->coords);
obj_coords.x1 -= ext_size;
obj_coords.y1 -= ext_size;
obj_coords.x2 += ext_size;
obj_coords.y2 += ext_size;
lv_obj_invalidate_area(obj, &obj_coords);
}
bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area)
{
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return false;
/*Invalidate the object only if it belongs to the current or previous'*/
lv_obj_t * obj_scr = lv_obj_get_screen(obj);
lv_disp_t * disp = lv_obj_get_disp(obj_scr);
if(obj_scr == lv_disp_get_scr_act(disp) ||
obj_scr == lv_disp_get_scr_prev(disp) ||
obj_scr == lv_disp_get_layer_top(disp) ||
obj_scr == lv_disp_get_layer_sys(disp)) {
/*Truncate the area to the object*/
lv_area_t obj_coords;
lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj);
lv_area_copy(&obj_coords, &obj->coords);
obj_coords.x1 -= ext_size;
obj_coords.y1 -= ext_size;
obj_coords.x2 += ext_size;
obj_coords.y2 += ext_size;
bool is_common;
is_common = _lv_area_intersect(area, area, &obj_coords);
if(is_common == false) return false; /*The area is not on the object*/
/*Truncate recursively to the parents*/
lv_obj_t * par = lv_obj_get_parent(obj);
while(par != NULL) {
is_common = _lv_area_intersect(area, area, &par->coords);
if(is_common == false) return false; /*If no common parts with parent break;*/
if(lv_obj_has_flag(par, LV_OBJ_FLAG_HIDDEN)) return false; /*If the parent is hidden then the child is hidden and won't be drawn*/
par = lv_obj_get_parent(par);
}
}
return true;
}
bool lv_obj_is_visible(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_area_t obj_coords;
lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj);
lv_area_copy(&obj_coords, &obj->coords);
obj_coords.x1 -= ext_size;
obj_coords.y1 -= ext_size;
obj_coords.x2 += ext_size;
obj_coords.y2 += ext_size;
return lv_obj_area_is_visible(obj, &obj_coords);
}
void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->ext_click_pad.x1 = left;
obj->spec_attr->ext_click_pad.x2 = right;
obj->spec_attr->ext_click_pad.y1 = top;
obj->spec_attr->ext_click_pad.y2 = bottom;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->ext_click_pad = LV_MAX4(left, right, top, bottom);
#else
LV_UNUSED(obj);
LV_UNUSED(left);
LV_UNUSED(right);
LV_UNUSED(top);
LV_UNUSED(bottom);
#endif
}
void lv_obj_get_click_area(const lv_obj_t * obj, lv_area_t * area)
{
lv_area_copy(area, &obj->coords);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
if(obj->spec_attr) {
area->x1 -= obj->spec_attr->ext_click_pad;
area->x2 += obj->spec_attr->ext_click_pad;
area->y1 -= obj->spec_attr->ext_click_pad;
area->y2 += obj->spec_attr->ext_click_pad;
}
#else
if(obj->spec_attr) {
area->x1 -= obj->spec_attr->ext_click_pad.x1;
area->x2 += obj->spec_attr->ext_click_pad.x2;
area->y1 -= obj->spec_attr->ext_click_pad.y1;
area->y2 += obj->spec_attr->ext_click_pad.y2;
}
#endif
}
bool lv_obj_hit_test(const lv_obj_t * obj, const lv_point_t * point)
{
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_ADV_HITTEST)) {
lv_hit_test_info_t hit_info;
hit_info.point = point;
hit_info.result = true;
lv_signal_send(obj, LV_SIGNAL_HIT_TEST, &hit_info);
return hit_info.result;
}
else {
lv_area_t a;
lv_obj_get_click_area(obj, &a);
return _lv_area_is_point_on(&a, point, 0);
}
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -211,6 +211,64 @@ lv_coord_t lv_obj_get_self_height(struct _lv_obj_t * obj);
*/
bool lv_obj_handle_self_size_chg(struct _lv_obj_t * obj);
/**
* Mark an area of an object as invalid.
* The area will be truncated to the object's area and marked for redraw.
* @param obj: pointer to an object
* @param area: the area to redraw
*/
void lv_obj_invalidate_area(const struct _lv_obj_t * obj, const lv_area_t * area);
/**
* Mark the object as invalid to redrawn its area
* @param obj: pointer to an object
*/
void lv_obj_invalidate(const struct _lv_obj_t * obj);
/**
* Tell whether an area of an object is visible (even partially) now or not
* @param obj: pointer to an object
* @param area: the are to check. The visible part of the area will be written back here.
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
*/
bool lv_obj_area_is_visible(const struct _lv_obj_t * obj, lv_area_t * area);
/**
* Tell whether an object is visible (even partially) now or not
* @param obj pointer to an object
* @return true: visible; false: not visible (hidden, out of parent, on other screen, etc)
*/
bool lv_obj_is_visible(const struct _lv_obj_t * obj);
/**
* Set the size of an extended clickable area
* If `LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY` in `lv_conf.h`,
* only the graetes value will be used.
* @param obj pointer to an object
* @param left extended clickable are on the left [px]
* @param right extended clickable are on the right [px]
* @param top extended clickable are on the top [px]
* @param bottom extended clickable are on the bottom [px]
*/
void lv_obj_set_ext_click_area(struct _lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom);
/**
* Get the an area where to object can be clicked.
* It's the object's normal area plus the extended click area.
* @param obj: pointer to an object
* @param area: store the result area here
*/
void lv_obj_get_click_area(const struct _lv_obj_t * obj, lv_area_t * area);
/**
* Hit-test an object given a particular point in screen space.
* @param obj object to hit-test
* @param point screen-space point (absolute coordinate)
* @return true: if the object is considered under the point
*/
bool lv_obj_hit_test(const struct _lv_obj_t * obj, const lv_point_t * point);
/**********************
* MACROS
**********************/

View File

@ -240,9 +240,8 @@ 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);
}
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->scroll.x += x;
obj->spec_attr->scroll.y += y;

View File

@ -29,10 +29,10 @@ struct _lv_obj_t;
/** Scrollbar modes: shows when should the scrollbars be visible*/
enum {
LV_SCROLLBAR_MODE_OFF = 0x0, /**< Never show scrollbars*/
LV_SCROLLBAR_MODE_ON = 0x1, /**< Always show scrollbars*/
LV_SCROLLBAR_MODE_ACTIVE = 0x2, /**< Show scroll bars when object is being scrolled*/
LV_SCROLLBAR_MODE_AUTO = 0x3, /**< Show scroll bars when the content is large enough to be scrolled*/
LV_SCROLLBAR_MODE_OFF, /**< Never show scrollbars*/
LV_SCROLLBAR_MODE_ON, /**< Always show scrollbars*/
LV_SCROLLBAR_MODE_ACTIVE, /**< Show scroll bars when object is being scrolled*/
LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/
};
typedef uint8_t lv_scrollbar_mode_t;

View File

@ -30,7 +30,7 @@ typedef struct {
uint8_t part;
lv_style_value_t start_value;
lv_style_value_t end_value;
} lv_style_trans_t;
} trans_t;
typedef enum {
CACHE_ZERO = 0,
@ -43,18 +43,20 @@ typedef enum {
/**********************
* STATIC PROTOTYPES
**********************/
static lv_style_t * get_local_style(lv_obj_t * obj, uint32_t part, uint32_t state);
static lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part);
static bool get_prop_core(const lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_value_t * v);
static lv_style_value_t apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v);
static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
static void report_style_change_core(void * style, lv_obj_t * obj);
static void refresh_children_style(lv_obj_t * obj);
#if LV_USE_ANIMATION
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit);
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v);
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, trans_t * tr_limit);
static void trans_anim_cb(trans_t * tr, lv_anim_value_t v);
static void trans_anim_start_cb(lv_anim_t * a);
static void trans_anim_ready_cb(lv_anim_t * a);
static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v);
static void fade_in_anim_ready(lv_anim_t * a);
#endif
static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
/**********************
* STATIC VARIABLES
@ -74,13 +76,19 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
*/
void _lv_obj_style_init(void)
{
_lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(lv_style_trans_t));
_lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(trans_t));
}
void lv_obj_add_style_no_refresh(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
/**
* Add a style to an object.
* @param obj: pointer to an object
* @param part: a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB`
* @param state: a state or combination of states to which the style should be assigned
* @param style: pointer to a style to add
* @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1);
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
if(style == NULL) return;
#if LV_USE_ANIMATION
trans_del(obj, part, 0xFF, NULL);
#endif
@ -109,43 +117,34 @@ void lv_obj_add_style_no_refresh(struct _lv_obj_t * obj, uint32_t part, uint32_t
obj->style_list.styles[i].part = part;
obj->style_list.styles[i].state = state;
lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**
* 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(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
lv_obj_add_style_no_refresh(obj, part, state, style);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**
* 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
* Add a style to an object.
* @param obj: pointer to an object
* @param part: a part of the object from which the style should be removed E.g. `LV_PART_MAIN` or `LV_PART_KNOB`
* @param state: a state or combination of states from which the style should be removed
* @param style: pointer to a style to remove
*/
void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
if(style == NULL) return;
uint32_t i;
/*Find the style*/
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].state == state &&
obj->style_list.styles[i].part == part) {
break;
}
uint32_t i = 0;
bool deleted = false;
while(i < obj->style_list.style_cnt) {
if((state != LV_STATE_ANY && obj->style_list.styles[i].state != state) ||
(part != LV_PART_ANY && obj->style_list.styles[i].part != part) ||
(style != NULL && style != obj->style_list.styles[i].style))
{
i++;
continue;
}
/*The style is not found*/
if(i == obj->style_list.style_cnt) return;
if(obj->style_list.styles[i].is_local || obj->style_list.styles[i].is_trans) {
lv_style_reset(obj->style_list.styles[i].style);
lv_mem_free(obj->style_list.styles[i].style);
obj->style_list.styles[i].style = NULL;
}
/*Shift the styles after `i` by one*/
uint32_t j;
@ -153,45 +152,22 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style
obj->style_list.styles[j] = obj->style_list.styles[j + 1];
}
obj->style_list.style_cnt--;
obj->style_list.styles = lv_mem_realloc(obj->style_list.styles, obj->style_list.style_cnt * sizeof(lv_obj_style_t));
#if LV_USE_ANIMATION
trans_del(obj, part, 0xFF, NULL);
#endif
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
deleted = true;
/* The style from the current `i` index is removed, so `i` points to the next style.
* Therefore it doesn't needs to be incremented*/
}
void lv_obj_remove_all_styles_no_refresh(lv_obj_t * obj)
{
#if LV_USE_ANIMATION
trans_del(obj, 0xFF, 0xFF, NULL);
#endif
lv_mem_free(obj->style_list.styles);
obj->style_list.styles = NULL;
obj->style_list.style_cnt = 0;
if(deleted) {
lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**
* 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_remove_all_styles(lv_obj_t * obj)
{
lv_obj_remove_all_styles_no_refresh(obj);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**
* Notify all object if a style is modified
* @param style pointer to a style. Only the objects with this style will be notified
* @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)
@ -208,168 +184,42 @@ 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
* Notify an object and its children about its style is modified.
* @param obj: pointer to an object
* @param prop: `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property.
* It is used to optimize what needs to be refreshed.
*/
bool lv_obj_remove_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop)
void lv_obj_refresh_style(lv_obj_t * obj,lv_style_prop_t prop)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
uint32_t i;
/*Find the style*/
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].is_local &&
obj->style_list.styles[i].state == state &&
obj->style_list.styles[i].part == part) {
break;
}
update_cache(obj, LV_PART_MAIN, prop);
lv_obj_invalidate(obj);
if(prop == LV_STYLE_PROP_ALL || (prop & LV_STYLE_PROP_LAYOUT_REFR)) {
lv_signal_send(obj, LV_SIGNAL_STYLE_CHG, NULL);
lv_obj_invalidate(obj);
} else if(prop & LV_STYLE_PROP_EXT_DRAW) {
lv_obj_refresh_ext_draw_size(obj);
lv_obj_invalidate(obj);
}
/*The style is not found*/
if(i == obj->style_list.style_cnt) return false;
return lv_style_remove_prop(obj->style_list.styles[i].style, 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)
if(prop == LV_STYLE_PROP_ALL ||
((prop & LV_STYLE_PROP_INHERIT) && (prop & LV_STYLE_PROP_EXT_DRAW) && (prop & LV_STYLE_PROP_LAYOUT_REFR)))
{
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)fade_anim_cb);
lv_anim_set_ready_cb(&a, fade_in_anim_ready);
lv_anim_set_time(&a, time);
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
refresh_children_style(obj);
}
}
/**
* 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)
{
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, LV_OPA_COVER, LV_OPA_TRANSP);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)fade_anim_cb);
lv_anim_set_time(&a, time);
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
}
#endif
static lv_style_value_t apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v)
{
if(obj == NULL) return v;
lv_color_filter_cb_t f = lv_obj_get_style_color_filter_cb(obj, part);
if(f) {
lv_opa_t f_opa = lv_obj_get_style_color_filter_opa(obj, part);
if(f_opa != 0) v.color = f(v.color, f_opa);
}
return v;
}
static bool get_prop_core(const lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_value_t * v)
{
cache_t cache_res = read_cache(obj, part, prop);
switch(cache_res) {
case CACHE_ZERO:
v->ptr = 0;
return true;
case CACHE_TRUE:
v->num = 1;
return true;
case CACHE_255:
v->num = 255;
return true;
case CACHE_UNSET:
return false;
case CACHE_NEED_CHECK:
break;
}
int32_t weight = -1;
lv_state_t state = obj->state;
lv_state_t state_inv = ~state;
lv_style_value_t value_tmp;
bool skip_trans = obj->style_list.skip_trans;
uint32_t i;
bool found;
for(i = 0; i < obj->style_list.style_cnt; i++) {
lv_obj_style_t * obj_style = &obj->style_list.styles[i];
if(obj_style->is_trans == false) break;
if(skip_trans) continue;
if(obj_style->part != part) continue;
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
if(found) {
*v = value_tmp;
return true;
}
}
for(; i < obj->style_list.style_cnt; i++) {
lv_obj_style_t * obj_style = &obj->style_list.styles[i];
if(obj_style->part != part) continue;
/* Be sure the style not specifies other state than the requested.
* E.g. For HOVER+PRESS object state, HOVER style only is OK, but HOVER+FOCUS style is not*/
if((obj_style->state & state_inv)) continue;
/*Check only better candidates*/
if(obj_style->state <= weight) continue;
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
if(found) {
if(obj_style->state == state) {
*v = value_tmp;
return true;
}
if(weight < obj_style->state) {
weight = obj_style->state;
*v = value_tmp;
}
}
}
if(weight >= 0) {
*v = value_tmp;
return true;
}
else return false;
}
/**
* 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
* Get the value of a style property. The current state of the object will be considered.
* Inherited properties will be inherited.
* If a property is not set a default value will be returned.
* @param obj: pointer to an object
* @param part: a part from which the property should be get
* @param prop: the property to get
* @return the value of the property.
* Should be read from the correct field of the `lv_style_value_t` according to the type of the property.
*/
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, uint8_t part, lv_style_prop_t prop)
{
@ -400,113 +250,49 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, uint8_t part, lv_st
return value_act;
}
/**
* 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.
* Set local style property on an object's part and state.
* @param obj: pointer to an object
* @param part: a part to which the property should be added
* @param state: a state to which the property should be added
* @param prop: the property
* @param value: value of the property. The correct element should be set according to the type of the property
*/
void _lv_obj_refresh_style(lv_obj_t * obj,lv_style_prop_t prop)
void lv_obj_set_local_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value)
{
lv_style_t * style = get_local_style(obj, part, state);
lv_style_set_prop(style, prop, value);
lv_obj_refresh_style(obj, prop);
}
/**
* 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.
* @param state: the state from which the property should be removed.
* @param prop: a style property to remove.
* @return true: the property was found and removed; false: the property was not found
*/
bool lv_obj_remove_local_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
update_cache(obj, LV_PART_MAIN, prop);
lv_obj_invalidate(obj);
if(prop == LV_STYLE_PROP_ALL || (prop & LV_STYLE_PROP_LAYOUT_REFR)) {
lv_signal_send(obj, LV_SIGNAL_STYLE_CHG, NULL);
lv_obj_invalidate(obj);
} else if(prop & LV_STYLE_PROP_EXT_DRAW) {
lv_obj_refresh_ext_draw_size(obj);
lv_obj_invalidate(obj);
}
if(prop == LV_STYLE_PROP_ALL ||
((prop & LV_STYLE_PROP_INHERIT) && (prop & LV_STYLE_PROP_EXT_DRAW) && (prop & LV_STYLE_PROP_LAYOUT_REFR)))
{
refresh_children_style(obj);
}
}
/**
* 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
trans_del(obj, 0xFF, 0xFF, NULL);
#else
LV_UNUSED(obj);
#endif
}
#if LV_USE_ANIMATION
lv_obj_style_t * _get_trans_style(lv_obj_t * obj, uint32_t part)
{
uint32_t i;
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].is_trans && obj->style_list.styles[i].part == part) break;
}
/*Already have a transition style for it*/
if(i != obj->style_list.style_cnt) return &obj->style_list.styles[i];
obj->style_list.style_cnt++;
obj->style_list.styles = lv_mem_realloc(obj->style_list.styles, obj->style_list.style_cnt * sizeof(lv_obj_style_t));
for(i = obj->style_list.style_cnt - 1; i > 0 ; i--) {
obj->style_list.styles[i] = obj->style_list.styles[i - 1];
}
lv_memset_00(&obj->style_list.styles[0], sizeof(lv_obj_style_t));
obj->style_list.styles[0].style = lv_mem_alloc(sizeof(lv_style_t));
lv_style_init(obj->style_list.styles[0].style);
obj->style_list.styles[0].is_trans = 1;
obj->style_list.styles[0].part = part;
return &obj->style_list.styles[0];
}
lv_style_t * lv_obj_get_local_style(lv_obj_t * obj, uint32_t part, uint32_t state)
{
uint32_t i;
/*Find the style*/
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].is_local &&
obj->style_list.styles[i].part == part &&
obj->style_list.styles[i].state == state)
{
return obj->style_list.styles[i].style;
obj->style_list.styles[i].state == state &&
obj->style_list.styles[i].part == part) {
break;
}
}
obj->style_list.style_cnt++;
obj->style_list.styles = lv_mem_realloc(obj->style_list.styles, obj->style_list.style_cnt * sizeof(lv_obj_style_t));
for(i = obj->style_list.style_cnt - 1; i > 0 ; i--) {
/* Copy only normal styles (not local and transition).
* The new local style will be added as the last local style*/
if(obj->style_list.styles[i - 1].is_local || obj->style_list.styles[i - 1].is_trans) break;
obj->style_list.styles[i] = obj->style_list.styles[i - 1];
}
lv_memset_00(&obj->style_list.styles[i], sizeof(lv_obj_style_t));
obj->style_list.styles[i].style = lv_mem_alloc(sizeof(lv_style_t));
lv_style_init(obj->style_list.styles[i].style);
obj->style_list.styles[i].is_local = 1;
obj->style_list.styles[i].part = part;
obj->style_list.styles[i].state = state;
return obj->style_list.styles[i].style;
}
void lv_obj_set_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value)
{
lv_style_t * style = lv_obj_get_local_style(obj, part, state);
lv_style_set_prop(style, prop, value);
_lv_obj_refresh_style(obj, prop);
/*The style is not found*/
if(i == obj->style_list.style_cnt) return false;
return lv_style_remove_prop(obj->style_list.styles[i].style, prop);
}
/**
@ -522,11 +308,10 @@ void lv_obj_set_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_sty
* @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_prop_t prop, uint8_t part, lv_state_t prev_state,
void lv_obj_style_create_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8_t part, lv_state_t prev_state,
lv_state_t new_state, uint32_t time, uint32_t delay, const lv_anim_path_t * path)
{
lv_style_trans_t * tr;
lv_obj_style_t * style_trans = _get_trans_style(obj, part);
trans_t * tr;
/*Get the previous and current values*/
obj->style_list.skip_trans = 1;
@ -540,6 +325,8 @@ void _lv_obj_create_style_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8
obj->state = prev_state;
v1 = lv_obj_get_style_prop(obj, part, prop);
obj->state = new_state;
lv_obj_style_t * style_trans = get_trans_style(obj, part);
lv_style_set_prop(style_trans->style, prop, v1); /*Be sure `trans_style` has a valid value */
if(prop == LV_STYLE_RADIUS) {
@ -577,8 +364,6 @@ void _lv_obj_create_style_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8
}
}
#endif
/**
* Compare the style properties of an object in 2 different states
* @param obj pointer to an object
@ -586,7 +371,7 @@ void _lv_obj_create_style_transition(lv_obj_t * obj, lv_style_prop_t prop, uint8
* @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)
_lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2)
{
lv_obj_style_list_t * list = &obj->style_list;
_lv_style_state_cmp_t res = _LV_STYLE_STATE_CMP_SAME;
@ -649,10 +434,203 @@ _lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t sta
return res;
}
#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)
{
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)fade_anim_cb);
lv_anim_set_ready_cb(&a, fade_in_anim_ready);
lv_anim_set_time(&a, time);
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
}
/**
* 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)
{
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, LV_OPA_COVER, LV_OPA_TRANSP);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)fade_anim_cb);
lv_anim_set_time(&a, time);
lv_anim_set_delay(&a, delay);
lv_anim_start(&a);
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Get the local style of an object for a given part and for a given state.
* If the local style for the part-state pair doesn't exist allocate and return it.
* @param obj: pointer to an object
* @param part: the part in whose local style to get
* @param state: the state in whose local style to get
* @return pointer to the local style
*/
static lv_style_t * get_local_style(lv_obj_t * obj, uint32_t part, uint32_t state)
{
uint32_t i;
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].is_local &&
obj->style_list.styles[i].part == part &&
obj->style_list.styles[i].state == state)
{
return obj->style_list.styles[i].style;
}
}
obj->style_list.style_cnt++;
obj->style_list.styles = lv_mem_realloc(obj->style_list.styles, obj->style_list.style_cnt * sizeof(lv_obj_style_t));
for(i = obj->style_list.style_cnt - 1; i > 0 ; i--) {
/* Copy only normal styles (not local and transition).
* The new local style will be added as the last local style*/
if(obj->style_list.styles[i - 1].is_local || obj->style_list.styles[i - 1].is_trans) break;
obj->style_list.styles[i] = obj->style_list.styles[i - 1];
}
lv_memset_00(&obj->style_list.styles[i], sizeof(lv_obj_style_t));
obj->style_list.styles[i].style = lv_mem_alloc(sizeof(lv_style_t));
lv_style_init(obj->style_list.styles[i].style);
obj->style_list.styles[i].is_local = 1;
obj->style_list.styles[i].part = part;
obj->style_list.styles[i].state = state;
return obj->style_list.styles[i].style;
}
/**
* Get the transition style of an object for a given part and for a given state.
* If the transition style for the part-state pair doesn't exist allocate and return it.
* @param obj: pointer to an object
* @param part: the part in whose local style to get
* @param state: the state in whose local style to get
* @return pointer to the transition style
*/
static lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part)
{
uint32_t i;
for(i = 0; i < obj->style_list.style_cnt; i++) {
if(obj->style_list.styles[i].is_trans && obj->style_list.styles[i].part == part) break;
}
/*Already have a transition style for it*/
if(i != obj->style_list.style_cnt) return &obj->style_list.styles[i];
obj->style_list.style_cnt++;
obj->style_list.styles = lv_mem_realloc(obj->style_list.styles, obj->style_list.style_cnt * sizeof(lv_obj_style_t));
for(i = obj->style_list.style_cnt - 1; i > 0 ; i--) {
obj->style_list.styles[i] = obj->style_list.styles[i - 1];
}
lv_memset_00(&obj->style_list.styles[0], sizeof(lv_obj_style_t));
obj->style_list.styles[0].style = lv_mem_alloc(sizeof(lv_style_t));
lv_style_init(obj->style_list.styles[0].style);
obj->style_list.styles[0].is_trans = 1;
obj->style_list.styles[0].part = part;
return &obj->style_list.styles[0];
}
static bool get_prop_core(const lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_value_t * v)
{
cache_t cache_res = read_cache(obj, part, prop);
switch(cache_res) {
case CACHE_ZERO:
v->ptr = 0;
return true;
case CACHE_TRUE:
v->num = 1;
return true;
case CACHE_255:
v->num = 255;
return true;
case CACHE_UNSET:
return false;
case CACHE_NEED_CHECK:
break;
}
int32_t weight = -1;
lv_state_t state = obj->state;
lv_state_t state_inv = ~state;
lv_style_value_t value_tmp;
bool skip_trans = obj->style_list.skip_trans;
uint32_t i;
bool found;
for(i = 0; i < obj->style_list.style_cnt; i++) {
lv_obj_style_t * obj_style = &obj->style_list.styles[i];
if(obj_style->is_trans == false) break;
if(skip_trans) continue;
if(obj_style->part != part) continue;
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
if(found) {
*v = value_tmp;
return true;
}
}
for(; i < obj->style_list.style_cnt; i++) {
lv_obj_style_t * obj_style = &obj->style_list.styles[i];
if(obj_style->part != part) continue;
/* Be sure the style not specifies other state than the requested.
* E.g. For HOVER+PRESS object state, HOVER style only is OK, but HOVER+FOCUS style is not*/
if((obj_style->state & state_inv)) continue;
/*Check only better candidates*/
if(obj_style->state <= weight) continue;
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
if(found) {
if(obj_style->state == state) {
*v = value_tmp;
return true;
}
if(weight < obj_style->state) {
weight = obj_style->state;
*v = value_tmp;
}
}
}
if(weight >= 0) {
*v = value_tmp;
return true;
}
else return false;
}
static lv_style_value_t apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v)
{
if(obj == NULL) return v;
lv_color_filter_cb_t f = lv_obj_get_style_color_filter_cb(obj, part);
if(f) {
lv_opa_t f_opa = lv_obj_get_style_color_filter_opa(obj, part);
if(f_opa != 0) v.color = f(v.color, f_opa);
}
return v;
}
static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
{
lv_obj_style_list_t * list = &obj->style_list;
@ -880,7 +858,7 @@ static void report_style_change_core(void * style, lv_obj_t * obj)
uint32_t i;
for(i = 0; i < list->style_cnt; i++) {
if(style == NULL || list->styles[i].style == style) {
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
break;
}
}
@ -908,7 +886,6 @@ static void refresh_children_style(lv_obj_t * obj)
}
}
#if LV_USE_ANIMATION
/**
* Remove the transition from object's part's property.
* - Remove the transition from `_lv_obj_style_trans_ll` and free it
@ -916,12 +893,12 @@ static void refresh_children_style(lv_obj_t * obj)
* @param obj pointer to an object which transition(s) should be removed
* @param part a part of object or 0xFF to remove from all parts
* @param prop a property or 0xFF to remove all properties
* @param tr_limit delete transitions only "older" then this. `NULL` is not used
* @param tr_limit delete transitions only "older" than this. `NULL` if not used
*/
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit)
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, trans_t * tr_limit)
{
lv_style_trans_t * tr;
lv_style_trans_t * tr_prev;
trans_t * tr;
trans_t * tr_prev;
bool removed = false;
tr = _lv_ll_get_tail(&LV_GC_ROOT(_lv_obj_style_trans_ll));
while(tr != NULL) {
@ -930,7 +907,7 @@ static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_sty
/*'tr' might be deleted, so get the next object while 'tr' is valid*/
tr_prev = _lv_ll_get_prev(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
if(tr->obj == obj && (part == tr->part || part == 0xFF) && (prop == tr->prop || prop == 0xFF)) {
if(tr->obj == obj && (part == tr->part || part == LV_PART_ANY) && (prop == tr->prop || prop == 0xFF)) {
/* Remove the transitioned property from trans. style
* to allow changing it by normal styles*/
uint32_t i;
@ -950,7 +927,7 @@ static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_sty
return removed;
}
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v)
static void trans_anim_cb(trans_t * tr, lv_anim_value_t v)
{
lv_obj_style_list_t * list = &tr->obj->style_list;
@ -1004,7 +981,7 @@ static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v)
}
}
lv_style_set_prop(list->styles[i].style, tr->prop, value_final);
if (refr) _lv_obj_refresh_style(tr->obj, tr->prop);
if (refr) lv_obj_refresh_style(tr->obj, tr->prop);
break;
}
@ -1013,7 +990,7 @@ static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v)
static void trans_anim_start_cb(lv_anim_t * a)
{
lv_style_trans_t * tr = a->var;
trans_t * tr = a->var;
tr->start_value = lv_obj_get_style_prop(tr->obj, tr->part, tr->prop);
@ -1026,14 +1003,14 @@ static void trans_anim_start_cb(lv_anim_t * a)
tr->prop = prop_tmp;
lv_obj_style_t * style_trans = _get_trans_style(tr->obj, tr->part);
lv_obj_style_t * style_trans = get_trans_style(tr->obj, tr->part);
lv_style_set_prop(style_trans->style, tr->prop, tr->start_value); /*Be sure `trans_style` has a valid value */
}
static void trans_anim_ready_cb(lv_anim_t * a)
{
lv_style_trans_t * tr = a->var;
trans_t * tr = a->var;
lv_obj_t * obj = tr->obj;
lv_style_prop_t prop = tr->prop;
@ -1041,7 +1018,7 @@ static void trans_anim_ready_cb(lv_anim_t * a)
* if there no more transitions for this property
* It allows changing it by normal styles*/
bool running = false;
lv_style_trans_t * tr_i;
trans_t * tr_i;
_LV_LL_READ(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr_i) {
if(tr_i != tr && tr_i->obj == tr->obj && tr_i->part == tr->part && tr_i->prop == tr->prop) {
running = true;
@ -1060,10 +1037,9 @@ static void trans_anim_ready_cb(lv_anim_t * a)
lv_style_remove_prop(obj_style->style, prop);
if(lv_style_is_empty(obj->style_list.styles[i].style)) {
lv_style_t * style = obj_style->style;
lv_obj_remove_style(obj, obj_style->part, obj_style->state, obj_style->style);
lv_style_reset(style);
lv_mem_free(style);
//trans_del(obj, obj_style->part, prop, NULL);
}
break;
}
@ -1073,7 +1049,7 @@ static void trans_anim_ready_cb(lv_anim_t * a)
static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v)
{
// lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, v);
// lv_obj_style_set_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, v);
}
static void fade_in_anim_ready(lv_anim_t * a)
@ -1081,5 +1057,4 @@ static void fade_in_anim_ready(lv_anim_t * a)
// lv_style_remove_prop(_lv_obj_get_local_style(a->var, LV_OBJ_PART_MAIN), LV_STYLE_OPA_SCALE);
}
#endif

View File

@ -15,12 +15,11 @@ extern "C" {
*********************/
#include <stdint.h>
#include <stdbool.h>
#include "../lv_misc/lv_style.h"
/*********************
* DEFINES
*********************/
#define LV_OBJ_STYLE_CACHE_STATE_INVALID 0x1ff
#define LV_OBJ_STYLE_CACHE_STATE_INVALID LV_STATE_ANY
/**********************
* TYPEDEFS
@ -46,8 +45,8 @@ typedef struct {
typedef struct {
lv_obj_style_t * styles;
uint32_t skip_trans :1;
uint32_t style_cnt :6;
uint32_t cache_state :9;
uint32_t style_cnt :5;
uint32_t cache_state :10;
uint32_t cache_opa_set :1;
uint32_t cache_radius_zero:1;
@ -82,107 +81,70 @@ typedef struct {
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)
* Add a style to an object.
* @param obj: pointer to an object
* @param part: a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB`
* @param state: a state or combination of states to which the style should be assigned
* @param style: pointer to a style to add
* @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1);
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, 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
* Add a style to an object.
* @param obj: pointer to an object
* @param part: a part of the object from which the style should be removed E.g. `LV_PART_MAIN` or `LV_PART_KNOB`
* @param state: a state or combination of states from which the style should be removed
* @param style: pointer to a style to remove
*/
void lv_obj_remove_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, 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_remove_all_styles(struct _lv_obj_t * obj);
void lv_obj_remove_style(struct _lv_obj_t * objj, uint32_t part, uint32_t state, lv_style_t * style);
/**
* Notify all object if a style is modified
* @param style pointer to a style. Only the objects with this style will be notified
* @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);
#if LV_USE_ANIMATION
/**
* Notify an object and its children about its style is modified.
* @param obj: pointer to an object
* @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(struct _lv_obj_t * obj,lv_style_prop_t prop);
/**
* 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]
* Get the value of a style property. The current state of the object will be considered.
* Inherited properties will be inherited.
* If a property is not set a default value will be returned.
* @param obj: pointer to an object
* @param part: a part from which the property should be get
* @param prop: the property to get
* @return the value of the property.
* Should be read from the correct field of the `lv_style_value_t` according to the type of the property.
*/
void lv_obj_fade_in(struct _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(struct _lv_obj_t * obj, uint32_t time, uint32_t delay);
#endif
lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, uint8_t part, lv_style_prop_t prop);
/**
* 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.
* Set local style property on an object's part and state.
* @param obj: pointer to an object
* @param part: a part to which the property should be added
* @param state: a state to which the property should be added
* @param prop: the property
* @param value: value of the property. The correct element should be set according to the type of the property
*/
void _lv_obj_refresh_style(struct _lv_obj_t * obj, lv_style_prop_t prop);
lv_style_t * lv_obj_get_local_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state);
/**
* Remove all transitions from an object
* @param obj pointer to an object
*/
void _lv_obj_remove_style_trans(struct _lv_obj_t * obj);
void lv_obj_set_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value);
#if LV_USE_ANIMATION
void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value);
/**
* 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
* 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.
* @param state: the state from which the property should be removed.
* @param prop: a style property to remove.
* @return true: the property was found and removed; false: the property was not found
*/
void _lv_obj_create_style_transition(struct _lv_obj_t * obj, lv_style_prop_t prop, uint8_t part, lv_state_t prev_state,
lv_state_t new_state, uint32_t time, uint32_t delay, const lv_anim_path_t * path);
#endif
/**
* 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(struct _lv_obj_t * obj, lv_state_t state1, lv_state_t state2);
bool lv_obj_remove_local_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop);
/*********************
* OBJ STYLE GET

379
src/lv_core/lv_obj_tree.c Normal file
View File

@ -0,0 +1,379 @@
/**
* @file lv_obj_tree.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_obj.h"
#include "lv_indev.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
#include "../lv_misc/lv_gc.h"
#include "../lv_misc/lv_async.h"
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_obj"
#if defined(LV_USER_DATA_FREE_INCLUDE)
#include LV_USER_DATA_FREE_INCLUDE
#endif /* LV_USE_USER_DATA_FREE */
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_event_mark_deleted(lv_obj_t * obj);
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_obj_del_async_cb(void * obj);
static void obj_del_core(lv_obj_t * obj);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_obj_t * lv_obj_create_from_class(const lv_obj_class_t * class, lv_obj_t * parent, const lv_obj_t * copy)
{
lv_obj_t * obj = lv_mem_alloc(class->instance_size);
lv_memset_00(obj, class->instance_size);
obj->class_p = class;
class->constructor(obj, parent, copy);
if(!copy) lv_theme_apply(obj);
// else lv_style_list_copy(&checkbox->style_indic, &checkbox_copy->style_indic);
return obj;
}
void lv_obj_construct_base(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{
const lv_obj_class_t * original_class_p = obj->class_p;
/*Don't let the descendant methods to run during constructing the ancestor type*/
obj->class_p = obj->class_p->base_class;
obj->class_p->constructor(obj, parent, copy);
/*Restore the original class*/
obj->class_p = original_class_p;
}
void lv_obj_del(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_invalidate(obj);
lv_disp_t * disp = NULL;
bool act_scr_del = false;
lv_obj_t * par = lv_obj_get_parent(obj);
if(par == NULL) {
disp = lv_obj_get_disp(obj);
if(!disp) return; /*Shouldn't happen*/
if(disp->act_scr == obj) act_scr_del = true;
}
obj_del_core(obj);
/*Send a signal to the parent to notify it about the child delete*/
if(par) {
lv_signal_send(par, LV_SIGNAL_CHILD_CHG, NULL);
}
/*Handle if the active screen was deleted*/
if(act_scr_del) {
disp->act_scr = NULL;
}
}
void lv_obj_clean(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
while(1) {
lv_obj_t * child = lv_obj_get_child(obj, 0);
obj_del_core(child);
}
}
void lv_obj_del_anim_ready_cb(lv_anim_t * a)
{
lv_obj_del(a->var);
}
void lv_obj_del_async(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_async_call(lv_obj_del_async_cb, obj);
}
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
LV_ASSERT_OBJ(parent, LV_OBJX_NAME);
if(obj->parent == NULL) {
LV_LOG_WARN("Can't set the parent of a screen");
return;
}
if(parent == NULL) {
LV_LOG_WARN("Can't set parent == NULL to an object");
return;
}
lv_obj_invalidate(obj);
lv_obj_allocate_spec_attr(parent);
lv_obj_t * old_parent = obj->parent;
lv_point_t old_pos;
old_pos.y = lv_obj_get_y(obj);
lv_bidi_dir_t new_base_dir = lv_obj_get_base_dir(parent);
if(new_base_dir != LV_BIDI_DIR_RTL) old_pos.x = lv_obj_get_x(obj);
else old_pos.x = old_parent->coords.x2 - obj->coords.x2;
/*Remove the object from the old parent's child list*/
int32_t i;
for(i = lv_obj_get_child_id(obj); i <= (int32_t)lv_obj_get_child_cnt(old_parent) - 2; i++) {
old_parent->spec_attr->children[i] = old_parent->spec_attr->children[i+1];
}
old_parent->spec_attr->child_cnt--;
if(old_parent->spec_attr->child_cnt) {
old_parent->spec_attr->children = lv_mem_realloc(old_parent->spec_attr->children, old_parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
} else {
lv_mem_free(old_parent->spec_attr->children);
old_parent->spec_attr->children = NULL;
}
/*Add the child to the new parent as the last (newest child)*/
parent->spec_attr->child_cnt++;
parent->spec_attr->children = lv_mem_realloc(parent->spec_attr->children, parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
parent->spec_attr->children[lv_obj_get_child_cnt(parent) - 1] = obj;
obj->parent = parent;
if(new_base_dir != LV_BIDI_DIR_RTL) {
lv_obj_set_pos(obj, old_pos.x, old_pos.y);
}
else {
/*Align to the right in case of RTL base dir*/
lv_coord_t new_x = lv_obj_get_width(parent) - old_pos.x - lv_obj_get_width(obj);
lv_obj_set_pos(obj, new_x, old_pos.y);
}
/*Notify the original parent because one of its children is lost*/
lv_signal_send(old_parent, LV_SIGNAL_CHILD_CHG, obj);
/*Notify the new parent about the child*/
lv_signal_send(parent, LV_SIGNAL_CHILD_CHG, obj);
lv_obj_invalidate(obj);
}
void lv_obj_move_foreground(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * parent = lv_obj_get_parent(obj);
lv_obj_invalidate(parent);
uint32_t i;
for(i = lv_obj_get_child_id(obj) - 1; i > 0; i--) {
parent->spec_attr->children[i] = parent->spec_attr->children[i-1];
}
parent->spec_attr->children[0] = obj;
/*Notify the new parent about the child*/
lv_signal_send(parent, LV_SIGNAL_CHILD_CHG, obj);
lv_obj_invalidate(parent);
}
void lv_obj_move_background(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * parent = lv_obj_get_parent(obj);
lv_obj_invalidate(parent);
uint32_t i;
for(i = lv_obj_get_child_id(obj); i < lv_obj_get_child_cnt(parent) - 2; i++) {
parent->spec_attr->children[i] = parent->spec_attr->children[i + 1];
}
parent->spec_attr->children[ lv_obj_get_child_cnt(parent) - 1] = obj;
/*Notify the new parent about the child*/
lv_signal_send(parent, LV_SIGNAL_CHILD_CHG, obj);
lv_obj_invalidate(parent);
}
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_obj_t * par = obj;
const lv_obj_t * act_par;
do {
act_par = par;
par = lv_obj_get_parent(act_par);
} while(par != NULL);
return (lv_obj_t*)act_par;
}
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_obj_t * scr;
if(obj->parent == NULL) scr = obj; /*`obj` is a screen*/
else scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
lv_disp_t * d;
_LV_LL_READ(&LV_GC_ROOT(_lv_disp_ll), d) {
uint32_t i;
for(i = 0; i < d->screen_cnt; i++) {
if(d->screens[i] == scr) return d;
}
}
LV_LOG_WARN("No screen found")
return NULL;
}
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->parent;
}
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t id)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr == NULL) return NULL;
if(id < 0) {
id = obj->spec_attr->child_cnt + id;
if(id < 0) return NULL;
}
if(id >= obj->spec_attr->child_cnt) return NULL;
else return obj->spec_attr->children[id];
}
uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr == NULL) return 0;
return obj->spec_attr->child_cnt;
}
uint32_t lv_obj_get_child_id(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent == NULL) return 0;
uint32_t i = 0;
for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
if(lv_obj_get_child(parent, i) == obj) return i;
}
return 0xFFFFFFFF; /*Shouldn't happen*/
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_obj_del_async_cb(void * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_del(obj);
}
static void obj_del_core(lv_obj_t * obj)
{
/*Let the user free the resources used in `LV_EVENT_DELETE`*/
lv_res_t res = lv_event_send(obj, LV_EVENT_DELETE, NULL);
if(res == LV_RES_INV) return;
/*Delete from the group*/
#if LV_USE_GROUP
lv_group_t * group = lv_obj_get_group(obj);
if(group) lv_group_remove_obj(obj);
#endif
/*Remove the animations from this object*/
#if LV_USE_ANIMATION
lv_anim_del(obj, NULL);
// _lv_obj_remove_style_trans(obj);
#endif
/*Delete the user data*/
#if LV_USE_USER_DATA
#if LV_USE_USER_DATA_FREE
LV_USER_DATA_FREE(obj);
#endif
#endif
/*Recursively delete the children*/
while(1) {
lv_obj_t * child = lv_obj_get_child(obj, 0);
obj_del_core(child);
}
lv_event_mark_deleted(obj);
/* Reset all input devices if the object to delete is used*/
lv_indev_t * indev = lv_indev_get_next(NULL);
while(indev) {
if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) {
lv_indev_reset(indev, obj);
}
if(indev->proc.types.pointer.last_pressed == obj) {
indev->proc.types.pointer.last_pressed = NULL;
}
#if LV_USE_GROUP
if(indev->group == group && obj == lv_indev_get_obj_act()) {
lv_indev_reset(indev, obj);
}
#endif
indev = lv_indev_get_next(indev);
}
/* All children deleted.
* Now clean up the object specific data*/
obj->class_p->destructor(obj);
}

164
src/lv_core/lv_obj_tree.h Normal file
View File

@ -0,0 +1,164 @@
/**
* @file struct _lv_obj_tree.h
*
*/
#ifndef LV_OBJ_TREE_H
#define LV_OBJ_TREE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stddef.h>
#include <stdbool.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
struct _lv_obj_t;
struct _lv_obj_class_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create an object form a class descriptor
* @param class pointer to a class
* @param parent pointer to an object where the new object should be created
* @param copy pointer to an other object with the same type to copy (DEPRECATED will be removed in v9)
* @return pointer to the created object
*/
struct _lv_obj_t * lv_obj_create_from_class(const struct _lv_obj_class_t * class, struct _lv_obj_t * parent, const struct _lv_obj_t * copy);
/**
* Used internally in widget's constructor to construct the base type
* @param obj pointer to the object being constructed
* @param parent pointer to the parent
* @param copy pointer to the object to copy (DEPRECATED will be removed in v9)
*/
void lv_obj_construct_base(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy);
/**
* Create a basic object
* @param parent pointer to a parent object.
* If NULL then a screen will be created
* @param copy pointer to a base object, if not NULL then the new object will be copied from it
* @return pointer to the new object
*/
void lv_obj_del(struct _lv_obj_t * obj);
/**
* Delete 'obj' and all of its children
* @param obj pointer to an object to delete
* @return LV_RES_INV because the object is deleted
*/
void lv_obj_clean(struct _lv_obj_t * obj);
/**
* A function to be easily used in animation ready callback to delete an object when the animation is ready
* @param a pointer to the animation
*/
void lv_obj_del_anim_ready_cb(lv_anim_t * a);
/**
* Helper function for asynchronously deleting objects.
* Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).
* @param obj object to delete
* @see lv_async_call
*/
void lv_obj_del_async(struct _lv_obj_t * obj);
/**
* Move the parent of an object. The relative coordinates will be kept.
*
* @param obj: pointer to an object whose parent needs to be changed
* @param parent: pointer to the new parent
*/
void lv_obj_set_parent(struct _lv_obj_t * obj, struct _lv_obj_t * parent);
/**
* Move the object to the foreground.
* It will look like if it was created as the last child of its parent.
* It also means it can cover any of the siblings.
* @param obj:pointer to an object
*/
void lv_obj_move_foreground(struct _lv_obj_t * obj);
/**
* Move the object to the background.
* It will look like if it was created as the first child of its parent.
* It also means any of the siblings can cover the object.
* @param obj:pointer to an object
*/
void lv_obj_move_background(struct _lv_obj_t * obj);
/**
* Get the screen of an object
* @param obj: pointer to an object
* @return pointer to the obejct's screen
*/
struct _lv_obj_t * lv_obj_get_screen(const struct _lv_obj_t * obj);
/**
* Get the display of the object
* @param obj: pointer to an object
* @return pointer to the obejct's display
*/
lv_disp_t * lv_obj_get_disp(const struct _lv_obj_t * obj);
/**
* Get the parent of an object
* @param obj: pointer to an object
* @return the parent of the object. (NULL if `obj` was a screen)
*/
struct _lv_obj_t * lv_obj_get_parent(const struct _lv_obj_t * obj);
/**
* Get the child of an object by the child's index.
* @param obj: pointer to an object whose child should be get
* @param id: the index of the child.
* 0: the oldest (firstly created) child
* 1: the second oldest
* child count-1: the youngest
* -1: the youngest
* -2: the second youngest
* @return pointer to the child or NULL if the index was invalid
*/
struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t id);
/**
* Get the number of children
* @param obj: pointer to an object
* @return the number of children
*/
uint32_t lv_obj_get_child_cnt(const struct _lv_obj_t * obj);
/**
* Get the index of a child.
* @param obj: pointer to an obejct
* @return the child index of the object.
* E.g. 0: the oldest (firstly created child)
*/
uint32_t lv_obj_get_child_id(const struct _lv_obj_t * obj);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_OBJ_TREE_H*/

View File

@ -685,7 +685,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 = _lv_obj_get_ext_draw_pad(obj);
lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj);
lv_obj_get_coords(obj, &obj_area);
obj_area.x1 -= ext_size;
obj_area.y1 -= ext_size;
@ -727,7 +727,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
lv_obj_get_coords(child, &child_area);
ext_size = _lv_obj_get_ext_draw_pad(child);
ext_size = _lv_obj_get_ext_draw_size(child);
child_area.x1 -= ext_size;
child_area.y1 -= ext_size;
child_area.x2 += ext_size;

View File

@ -151,8 +151,8 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
lv_obj_remove_all_styles(disp->top_layer);
lv_obj_remove_all_styles(disp->sys_layer);
lv_obj_remove_style(disp->top_layer, LV_PART_ANY, LV_STATE_ANY, NULL);
lv_obj_remove_style(disp->sys_layer, LV_PART_ANY, LV_STATE_ANY, NULL);
lv_obj_clear_flag(disp->top_layer, LV_OBJ_FLAG_CLICKABLE);
lv_obj_clear_flag(disp->sys_layer, LV_OBJ_FLAG_CLICKABLE);

View File

@ -51,12 +51,12 @@ enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
typedef uint8_t lv_indev_state_t;
enum {
LV_SCROLL_DIR_NONE,
LV_SCROLL_DIR_HOR,
LV_SCROLL_DIR_VER,
LV_INDEV_SCROLL_DIR_NONE,
LV_INDEV_SCROLL_DIR_HOR,
LV_INDEV_SCROLL_DIR_VER,
};
typedef uint8_t lv_scroll_dir_t;
typedef uint8_t lv_indev_scroll_dir_t;
enum {
LV_GESTURE_DIR_TOP, /**< Gesture dir up. */
@ -144,7 +144,7 @@ typedef struct _lv_indev_proc_t {
lv_gesture_dir_t gesture_dir;
lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
/*Flags*/
lv_scroll_dir_t scroll_dir : 2;
lv_indev_scroll_dir_t scroll_dir : 2;
uint8_t gesture_sent : 1;
} pointer;
struct {

View File

@ -59,7 +59,7 @@ void _lv_anim_core_init(void)
last_task_run = lv_tick_get();
_lv_anim_tmr = lv_timer_create(anim_task, LV_DISP_DEF_REFR_PERIOD, NULL);
anim_mark_list_change(); /*Turn off the animation task*/
anim_list_changed = false; /*The list has not actually changed*/
anim_list_changed = false;
}
/**

View File

@ -1,89 +0,0 @@
///**
// * @file lv_class.c
// *
// */
//
///*********************
// * INCLUDES
// *********************/
//#include "lv_class.h"
//#include "lv_mem.h"
//
///*********************
// * DEFINES
// *********************/
//
///**********************
// * TYPEDEFS
// **********************/
//
///**********************
// * STATIC PROTOTYPES
// **********************/
//
///**********************
// * STATIC VARIABLES
// **********************/
//lv_base_class_t lv_base;
//
///**********************
// * MACROS
// **********************/
//
///**********************
// * GLOBAL FUNCTIONS
// **********************/
//
//void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size, void * base_p)
//{
// lv_base_class_t * c = class_p;
// const lv_base_class_t * bc = base_p;
// lv_memset_00(c, class_size);
//
// /*By default use the same methods as the base*/
// if(bc) lv_memcpy(c, base_p, bc->_class_size);
//
// c->base_p = base_p; /*Save the base to allow accessing its methods later*/
// c->init = NULL;
// c->constructor = NULL;
// c->_instance_size = instance_size;
// c->_class_size = class_size;
// c->_inited = 1;
//}
//
//void * lv_class_new(void * class_p)
//{
// lv_base_class_t * base_class_p = class_p;
// lv_base_t * instance = lv_mem_alloc(base_class_p->_instance_size);
// lv_memset_00(instance, base_class_p->_instance_size);
// instance->class_p = class_p;
// return instance;
//}
//
//
//void lv_class_destroy(void * instance)
//{
// lv_mem_free(instance);
//}
//
///**********************
// * STATIC FUNCTIONS
// **********************/
//
////static void desctructor_chain(void * inst)
////{
//// lv_base_t * base_inst = inst;
//// if(base->)
////}
//
///**
// * Constructor of the base class. Just zero out the instance
// * @param inst pointer to an instance
// */
//void lv_class_base_construct(void * inst)
//{
// lv_base_t * base_inst = inst;
// void * class_p = base_inst->class_p;
// lv_memset_00(inst, base_inst->class_p->_instance_size);
// base_inst->class_p = class_p; /*Restore class dsc pointer*/
//}

View File

View File

@ -153,13 +153,17 @@ void lv_mem_deinit(void)
*/
void * lv_mem_alloc(size_t size)
{
if(size == 0) {
printf("alloc: 0\n");
return &zero_mem;
}
/*Round the size up to ALIGN_MASK*/
size = (size + ALIGN_MASK) & (~ALIGN_MASK);
void * alloc = NULL;
printf("alloc: %d\n", size);
#if LV_MEM_CUSTOM == 0
alloc = alloc_core(size);
@ -217,12 +221,17 @@ void * lv_mem_alloc(size_t size)
*/
void lv_mem_free(const void * data)
{
if(data == &zero_mem) return;
if(data == &zero_mem) {
printf("free: %d\n", 0);
return;
}
if(data == NULL) return;
#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));
printf("free: %d\n", e->header.s.d_size);
# if LV_MEM_ADD_JUNK
lv_memset((void *)data, 0xbb, lv_mem_get_size(data));
# endif
@ -291,9 +300,8 @@ void * lv_mem_realloc(void * data_p, size_t new_size)
if(data_p != NULL) {
/*Copy the old data to the new. Use the smaller size*/
if(old_size != 0) {
if(old_size != 0 && new_size != 0) {
lv_memcpy(new_p, data_p, LV_MIN(new_size, old_size));
lv_mem_free(data_p);
}
lv_mem_free(data_p);
}

View File

@ -70,6 +70,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
if(!style->allocated) {
if(style->prop1 == prop) {
style->prop1 = LV_STYLE_PROP_INV;
style->prop_cnt = 0;
return true;
}
return false;

View File

@ -60,12 +60,12 @@ lv_theme_t * lv_theme_get_act(void)
*/
void lv_theme_apply(lv_obj_t * obj)
{
lv_obj_remove_all_styles_no_refresh(obj);
lv_obj_remove_style(obj, LV_PART_ANY, LV_STATE_ANY, NULL);
/*Apply the theme including the base theme(s)*/
apply_theme(act_theme, obj);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**

View File

@ -300,7 +300,7 @@ static void basic_init(void)
style_init_reset(&styles->grow);
lv_style_set_transform_width(&styles->grow, LV_DPX(3));
lv_style_set_transform_angle(&styles->grow, LV_DPX(3));
lv_style_set_transform_height(&styles->grow, LV_DPX(3));
style_init_reset(&styles->knob);
lv_style_set_bg_color(&styles->knob, IS_LIGHT ? theme.color_primary : LV_COLOR_WHITE);
@ -479,158 +479,158 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
LV_UNUSED(th);
if(lv_obj_get_parent(obj) == NULL) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
return;
}
if(lv_obj_check_type(obj, &lv_obj)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
}
#if LV_USE_BTN
else if(lv_obj_check_type(obj, &lv_btn)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->bg_color_secondary);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->bg_color_secondary);
}
#endif
#if LV_USE_BTNMATRIX
else if(lv_obj_check_type(obj, &lv_btnmatrix)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->transition_normal);
}
#endif
#if LV_USE_BAR
else if(lv_obj_check_type(obj, &lv_bar)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
}
#endif
#if LV_USE_SLIDER
else if(lv_obj_check_type(obj, &lv_slider)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal);
}
#endif
#if LV_USE_TABLE
else if(lv_obj_check_type(obj, &lv_table)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_SCROLLED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->table_cell);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->pad_small);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_SCROLLED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->table_cell);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->pad_small);
}
#endif
#if LV_USE_CHECKBOX
else if(lv_obj_check_type(obj, &lv_checkbox)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_gap);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed);
}
#endif
#if LV_USE_SWITCH
else if(lv_obj_check_type(obj, &lv_switch)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative);
}
#endif
#if LV_USE_CHART
else if(lv_obj_check_type(obj, &lv_chart)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_dashed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->chart_series);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->pad_small);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->chart_ticks);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_dashed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->chart_series);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->pad_small);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->chart_ticks);
}
#endif
#if LV_USE_ROLLER
else if(lv_obj_check_type(obj, &lv_roller)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->anim);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->anim);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_primary);
}
#endif
#if LV_USE_DROPDOWN
else if(lv_obj_check_type(obj, &lv_dropdown)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->ddlist_flip);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->ddlist_flip);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_normal);
}
else if(lv_obj_check_type(obj, &lv_dropdown_list)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_PRESSED, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_PRESSED, &styles->bg_color_gray);
}
#endif
#if LV_USE_ARC
else if(lv_obj_check_type(obj, &lv_arc)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->arc_indic);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->arc_indic);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->arc_indic_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->arc_indic);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->arc_indic);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->arc_indic_primary);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
}
#endif
#if LV_USE_METER
else if(lv_obj_check_type(obj, &lv_meter)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->meter_marker);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->meter_marker);
}
#endif
#if LV_USE_TEXTAREA
else if(lv_obj_check_type(obj, &lv_textarea)) {
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->ta_cursor);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->ta_cursor);
}
#endif

View File

@ -47,6 +47,7 @@ const lv_obj_class_t lv_arc = {
.signal_cb = lv_arc_signal,
.draw_cb = lv_arc_draw,
.instance_size = sizeof(lv_arc_t),
.editable = 1,
.base_class = &lv_obj
};
@ -708,12 +709,6 @@ static lv_res_t lv_arc_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(res != LV_RES_OK) return res;
}
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = true;
#endif
}
return res;
}

View File

@ -59,6 +59,7 @@ const lv_obj_class_t lv_btnmatrix = {
.signal_cb = lv_btnmatrix_signal,
.draw_cb = lv_btnmatrix_draw,
.instance_size = sizeof(lv_btnmatrix_t),
.editable = 1,
.base_class = &lv_obj
};
@ -993,12 +994,6 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par
btnm->btn_id_act = btnm->btn_id_focused;
lv_obj_invalidate(obj);
}
#endif
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = true;
#endif
}
return res;

View File

@ -1133,14 +1133,14 @@ static void draw_cursors(lv_obj_t * obj, const lv_area_t * clip_area)
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_CURSOR, &line_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_MARKER, &line_dsc);
lv_draw_rect_dsc_t point_dsc;
lv_draw_rect_dsc_init(&point_dsc);
point_dsc.bg_opa = line_dsc.opa;
point_dsc.radius = LV_RADIUS_CIRCLE;
lv_coord_t point_radius = lv_obj_get_style_size(chart, LV_PART_CURSOR);
lv_coord_t point_radius = lv_obj_get_style_size(chart, LV_PART_MARKER);
/*Do not bother with line ending is the point will over it*/
if(point_radius > line_dsc.width / 2) line_dsc.raw_end = 1;
@ -1461,7 +1461,7 @@ static void invalidate_point(lv_obj_t * obj, uint16_t i)
_lv_inv_area(lv_obj_get_disp(obj), &col_a);
} else {
lv_obj_invalidate(chart);
lv_obj_invalidate(obj);
}
}

View File

@ -290,6 +290,13 @@ static lv_res_t lv_checkbox_signal(lv_obj_t * obj, lv_signal_t sign, void * para
lv_coord_t m = lv_obj_calculate_ext_draw_size(obj, LV_PART_MARKER);
*s = LV_MAX(*s, m);
}
else if(sign == LV_SIGNAL_RELEASED) {
uint32_t v = lv_obj_get_state(obj) & LV_STATE_CHECKED ? 1 : 0;
res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &v);
if(res != LV_RES_OK) return res;
lv_obj_invalidate(obj);
}
return res;
}

View File

@ -66,6 +66,7 @@ const lv_obj_class_t lv_dropdown = {
.signal_cb = lv_dropdown_signal,
.draw_cb = lv_dropdown_draw,
.instance_size = sizeof(lv_dropdown_t),
.editable = 1,
.base_class = &lv_obj
};
@ -983,12 +984,6 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * obj, lv_signal_t sign, void * para
}
#endif
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = true;
#endif
}
return res;
}
@ -1037,8 +1032,8 @@ static void draw_box(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint1
}
/*Draw a rectangle under the selected item*/
const lv_font_t * font = lv_obj_get_style_text_font(list_obj, LV_PART_HIGHLIGHT);
lv_coord_t line_space = lv_obj_get_style_text_line_space(list_obj, LV_PART_HIGHLIGHT);
const lv_font_t * font = lv_obj_get_style_text_font(list_obj, LV_PART_SELECTED);
lv_coord_t line_space = lv_obj_get_style_text_line_space(list_obj, LV_PART_SELECTED);
lv_coord_t font_h = lv_font_get_line_height(font);
/*Draw the selected*/
@ -1054,7 +1049,7 @@ static void draw_box(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint1
lv_draw_rect_dsc_t sel_rect;
lv_draw_rect_dsc_init(&sel_rect);
lv_obj_init_draw_rect_dsc(list_obj, LV_PART_HIGHLIGHT, &sel_rect);
lv_obj_init_draw_rect_dsc(list_obj, LV_PART_SELECTED, &sel_rect);
lv_draw_rect(&rect_area, clip_area, &sel_rect);
list_obj->state = state_orig;
@ -1072,9 +1067,9 @@ static void draw_box_label(lv_obj_t * dropdown_obj, const lv_area_t * clip_area,
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_obj_init_draw_label_dsc(list_obj, LV_PART_HIGHLIGHT, &label_dsc);
lv_obj_init_draw_label_dsc(list_obj, LV_PART_SELECTED, &label_dsc);
label_dsc.line_space = lv_obj_get_style_text_line_space(list_obj, LV_PART_HIGHLIGHT); /*Line space should come from the list*/
label_dsc.line_space = lv_obj_get_style_text_line_space(list_obj, LV_PART_SELECTED); /*Line space should come from the list*/
lv_obj_t * label = get_label(dropdown_obj);
if(label == NULL) return;
@ -1183,7 +1178,6 @@ static uint16_t get_id_on_point(lv_obj_t * dropdown_obj, lv_coord_t y)
static void position_to_selected(lv_obj_t * dropdown_obj)
{
lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj;
lv_obj_t * list_obj = dropdown->list;
lv_obj_t * label = get_label(dropdown_obj);
if(label == NULL) return;

View File

@ -740,8 +740,11 @@ static lv_res_t lv_img_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
info->result = _lv_area_is_point_on(&coords, info->point, 0);
}
else
info->result = _lv_obj_is_click_point_on(obj, info->point);
else {
lv_area_t a;
lv_obj_get_click_area(obj, &a);
info->result = _lv_area_is_point_on(&a, info->point, 0);
}
}
else if(sign == LV_SIGNAL_GET_SELF_SIZE) {
lv_point_t * p = param;

View File

@ -101,7 +101,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");

View File

@ -1132,8 +1132,8 @@ static lv_draw_res_t lv_label_draw(lv_obj_t * obj, const lv_area_t * clip_area,
label_draw_dsc.sel_start = lv_label_get_text_sel_start(obj);
label_draw_dsc.sel_end = lv_label_get_text_sel_end(obj);
if(label_draw_dsc.sel_start != LV_DRAW_LABEL_NO_TXT_SEL && label_draw_dsc.sel_end != LV_DRAW_LABEL_NO_TXT_SEL) {
label_draw_dsc.sel_color = lv_obj_get_style_text_color_filtered(obj, LV_PART_HIGHLIGHT);
label_draw_dsc.sel_bg_color = lv_obj_get_style_bg_color(obj, LV_PART_HIGHLIGHT);
label_draw_dsc.sel_color = lv_obj_get_style_text_color_filtered(obj, LV_PART_SELECTED);
label_draw_dsc.sel_bg_color = lv_obj_get_style_bg_color(obj, LV_PART_SELECTED);
}
/* In SROLL and SROLL_CIRC mode the CENTER and RIGHT are pointless so remove them.

View File

@ -389,14 +389,14 @@ static lv_draw_res_t lv_roller_draw(lv_obj_t * obj, const lv_area_t * clip_area,
lv_draw_rect_dsc_t sel_dsc;
lv_draw_rect_dsc_init(&sel_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_PART_HIGHLIGHT, &sel_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_PART_SELECTED, &sel_dsc);
lv_draw_rect(&rect_area, clip_area, &sel_dsc);
}
/*Post draw when the children are drawn*/
else if(mode == LV_DRAW_MODE_POST_DRAW) {
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_obj_init_draw_label_dsc(obj, LV_PART_HIGHLIGHT, &label_dsc);
lv_obj_init_draw_label_dsc(obj, LV_PART_SELECTED, &label_dsc);
lv_coord_t bg_font_h = lv_font_get_line_height(lv_obj_get_style_text_font(obj, LV_PART_MAIN));
@ -844,8 +844,8 @@ static lv_coord_t get_selected_label_width(const lv_obj_t * obj)
lv_obj_t * label = get_label(obj);
if(label == NULL) return 0;
const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_HIGHLIGHT);
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_HIGHLIGHT);
const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_SELECTED);
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_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_TEXT_FLAG_NONE);

View File

@ -48,6 +48,7 @@ const lv_obj_class_t lv_slider = {
.destructor = lv_slider_destructor,
.signal_cb = lv_slider_signal,
.draw_cb = lv_slider_draw,
.editable = 1,
.instance_size = sizeof(lv_slider_t),
.base_class = &lv_bar
};
@ -379,12 +380,6 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
}
#endif
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = true;
#endif
}
return res;
}

View File

@ -224,14 +224,12 @@ static lv_res_t lv_switch_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
*s = LV_MAX(*s, lv_obj_calculate_ext_draw_size(obj, LV_PART_INDICATOR));
}
else if(sign == LV_SIGNAL_RELEASED) {
uint32_t v = lv_obj_get_state(obj) & LV_STATE_CHECKED ? 1 : 0;
res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &v);
if(res != LV_RES_OK) return res;
lv_obj_invalidate(obj);
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = false; /*The ancestor slider is editable the switch is not*/
#endif
}
return res;
}

View File

@ -72,6 +72,7 @@ const lv_obj_class_t lv_textarea = {
.destructor = lv_textarea_destructor,
.signal_cb = lv_textarea_signal,
.draw_cb = lv_textarea_draw,
.editable = 1,
.instance_size = sizeof(lv_textarea_t),
.base_class = &lv_obj
};
@ -1152,12 +1153,6 @@ static lv_res_t lv_textarea_signal(lv_obj_t * obj, lv_signal_t sign, void * para
else {
lv_textarea_add_char(obj, c);
}
#endif
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP
bool * editable = (bool *)param;
*editable = true;
#endif
}
else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING || sign == LV_SIGNAL_PRESS_LOST ||