1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

Merge branch 'lv_group' into beta

This commit is contained in:
Gabor 2017-07-25 09:05:18 +02:00
commit cd83e6febc
20 changed files with 1261 additions and 312 deletions

View File

@ -47,6 +47,7 @@
/*lv_obj (base object) settings*/
#define LV_OBJ_FREE_NUM 1 /*Enable the free number attribute*/
#define LV_OBJ_FREE_P 1 /*Enable the free pointer attribute*/
#define LV_OBJ_GROUP 1 /*Enable object groups*/
/*Others*/
#define LV_COLOR_TRANSP COLOR_LIME
@ -145,6 +146,9 @@
/*List (dependencies: lv_page, lv_btn, lv_label, lv_img)*/
#define USE_LV_LIST 1
#if USE_LV_LIST != 0
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
#endif
/*Drop down list (dependencies: lv_page, lv_label)*/
#define USE_LV_DDLIST 1
@ -244,7 +248,6 @@
#define LV_APP_FILES_CHUNK_MAX_SIZE 1024 /*Max chunk size when the user sets it*/
#endif /*USE_LV_APP_FILES != 0*/
/*Benchmark*/
#define USE_LV_APP_BENCHMARK 1
#if USE_LV_APP_BENCHMARK != 0
@ -252,7 +255,7 @@
#endif
/*WiFi*/
#define USE_LV_APP_WIFI 1
#define USE_LV_APP_WIFI 0
#if USE_LV_APP_WIFI != 0
#define LV_APP_WIFI_CONF_PATH "S:/wifi_conf.txt" /*Save config. here. Comment to use def. value*/
#ifndef LV_APP_WIFI_CONF_PATH
@ -265,7 +268,7 @@
#endif /*USE_LV_APP_WIFI != 0*/
/*GSM*/
#define USE_LV_APP_GSM 1
#define USE_LV_APP_GSM 0
#if USE_LV_APP_GSM != 0
#define LV_APP_GSM_CONF_PATH "S:/gsm_conf.txt" /*Save config. here. Comment to use def. value*/
#ifndef LV_APP_GSM_CONF_PATH
@ -277,7 +280,7 @@
#endif /*USE_LV_APP_GSM != 0*/
/*Ethernet*/
#define USE_LV_APP_ETHERNET 1
#define USE_LV_APP_ETHERNET 0
#if USE_LV_APP_ETHERNET != 0
/*No settings*/
#endif /*USE_LV_APP_ETHERNET != 0*/

240
lv_obj/lv_group.c Normal file
View File

@ -0,0 +1,240 @@
/**
* @file lv_group.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_group.h"
#if LV_OBJ_GROUP != 0
#include <stddef.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void style_mod_def(lv_style_t * style);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a new object group
* @return pointer to the new object group
*/
lv_group_t * lv_group_create(void)
{
lv_group_t * group = dm_alloc(sizeof(lv_group_t));
ll_init(&group->obj_ll, sizeof(lv_obj_t *));
group->style_mod = style_mod_def;
group->obj_focus = NULL;
return group;
}
/**
* Add an object to a group
* @param group pointer to a group
* @param obj pointer to an object to add
*/
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
{
obj->group_p = group;
lv_obj_t ** next = ll_ins_tail(&group->obj_ll);
*next = obj;
/* If the head and the tail is equal then there is only one object in the linked list.
* In this case automatically activate it*/
if(ll_get_head(&group->obj_ll) == next) {
lv_group_focus_next(group);
}
}
/**
* Remove an object from its group
* @param obj pointer to an objectto remove
*/
void lv_group_rem_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
ll_rem(&g->obj_ll, i);
break;
}
}
}
/**
* Focus on an object (defocus the current)
* @param obj pointer to an object to focus on
*/
void lv_group_focus_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
if(g->obj_focus != NULL) {
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*g->obj_focus);
}
g->obj_focus = i;
if(g->obj_focus != NULL){
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*g->obj_focus);
}
break;
}
}
}
/**
* Focus the next object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_next(lv_group_t * group)
{
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = ll_get_head(&group->obj_ll);
else obj_next = ll_get_next(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = ll_get_head(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus != NULL){
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
}
/**
* Focus the previous object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_prev(lv_group_t * group)
{
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = ll_get_tail(&group->obj_ll);
else obj_next = ll_get_prev(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = ll_get_tail(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus != NULL){
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_inv(*group->obj_focus);
}
}
/**
* Send a control character to the focuses object of a group
* @param group pointer to a group
* @param c a control character (use LV_GROUP_KEY_.. to navigate)
*/
void lv_group_send(lv_group_t * group, char c)
{
lv_obj_t * act = lv_group_get_focused(group);
if(act == NULL) return;
act->signal_f(act, LV_SIGNAL_CONTROLL, &c);
}
/**
* Set a function for a group which will modify the object's style if it is in focus
* @param group pointer to a group
* @param style_cb the style modifier function pointer
*/
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style))
{
group->style_mod = style_cb;
if(group->obj_focus != NULL) lv_obj_inv(*group->obj_focus);
}
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
* @param style pointer to a style to modify
* @return a copy of the input style but modified with the 'style_mod' function
*/
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
{
lv_style_cpy(&group->style_tmp, style);
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
else style_mod_def(&group->style_tmp);
return &group->style_tmp;
}
/**
* Get the focused object or NULL if there isn't one
* @param group pointer to a group
* @return pointer to the focused object
*/
lv_obj_t * lv_group_get_focused(lv_group_t * group)
{
if(group == NULL) return NULL;
if(group->obj_focus == NULL) return NULL;
return *group->obj_focus;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Default style modifier function
* @param style pointer to a style to modify. (Typically &group->style_tmp) It will be OVERWRITTEN.
*/
static void style_mod_def(lv_style_t * style)
{
/*Make the style a little bit orange*/
style->bcolor = COLOR_ORANGE;
style->bopa = OPA_COVER;
if(style->bwidth == 0 && style->empty == 0) style->bwidth = 2 * LV_DOWNSCALE; /*Add border to not transparent styles*/
else style->bwidth = style->bwidth * 2; /*Make the border thicker*/
style->mcolor = color_mix(style->mcolor, COLOR_ORANGE, OPA_80);
style->gcolor = color_mix(style->gcolor, COLOR_ORANGE, OPA_80);
}
#endif /*LV_OBJ_GROUP != 0*/

67
lv_obj/lv_group.h Normal file
View File

@ -0,0 +1,67 @@
/**
* @file lv_group.h
*
*/
#ifndef LV_GROUP_H
#define LV_GROUP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#include "lv_obj.h"
/*********************
* DEFINES
*********************/
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
/*For compatibility in signal function define the keys regardless to LV_OBJ_GROUP*/
#define LV_GROUP_KEY_UP 17 /*0x11*/
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
#define LV_GROUP_KEY_ESC 33 /*0x1B*/
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
#if LV_OBJ_GROUP != 0
/**********************
* TYPEDEFS
**********************/
typedef struct
{
ll_dsc_t obj_ll;
lv_obj_t ** obj_focus;
void (*style_mod)(lv_style_t * style);
lv_style_t style_tmp;
}lv_group_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
lv_group_t * lv_group_create(void);
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
void lv_group_rem_obj(lv_obj_t * obj);
void lv_group_focus_obj(lv_obj_t * obj);
void lv_group_focus_next(lv_group_t * group);
void lv_group_focus_prev(lv_group_t * group);
void lv_group_send(lv_group_t * group, char c);
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
lv_obj_t * lv_group_get_focused(lv_group_t * group);
/**********************
* MACROS
**********************/
#endif /*LV_OBJ_GROUP != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_GROUP_H*/

View File

@ -12,8 +12,10 @@
#include "lvgl/lv_obj/lv_dispi.h"
#include "lvgl/lv_obj/lv_obj.h"
#include "lvgl/lv_obj/lv_refr.h"
#include "lvgl/lv_obj/lv_group.h"
#include "lvgl/lv_app/lv_app.h"
#include "lvgl/lv_draw/lv_draw_rbasic.h"
#include "lv_group.h"
#include "misc/gfx/anim.h"
#include "hal/indev/indev.h"
#include <stdint.h>
@ -141,10 +143,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
#if LV_OBJ_FREE_NUM != 0
new_obj->free_num = 0;
#endif
#if LV_OBJ_FREE_P != 0
new_obj->free_p = NULL;
#endif
#if LV_OBJ_GROUP != 0
new_obj->group_p = NULL;
#endif
/*Set attributes*/
new_obj->click_en = 0;
new_obj->drag_en = 0;
@ -187,6 +193,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
#if LV_OBJ_FREE_P != 0
new_obj->free_p = NULL;
#endif
#if LV_OBJ_GROUP != 0
new_obj->group_p = NULL;
#endif
/*Set attributes*/
new_obj->click_en = 1;
@ -198,7 +207,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->protect = LV_PROTECT_NONE;
new_obj->ext = NULL;
}
if(copy != NULL) {
@ -223,6 +231,13 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->style_p = copy->style_p;
#if LV_OBJ_GROUP != 0
/*Add to the same group*/
if(copy->group_p != NULL) {
lv_group_add_obj(copy->group_p, new_obj);
}
#endif
lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy));
}
@ -1234,20 +1249,28 @@ cord_t lv_obj_get_ext_size(lv_obj_t * obj)
*/
lv_style_t * lv_obj_get_style(lv_obj_t * obj)
{
if(obj->style_p != NULL) return obj->style_p;
else {
lv_style_t * style_act = obj->style_p;
if(style_act == NULL) {
lv_obj_t * par = obj->par;
while(par != NULL) {
if(par->style_p != NULL) {
if(par->style_p->glass == 0) return par->style_p;
if(par->style_p->glass == 0) {
style_act = par->style_p;
break;
}
}
par = par->par;
}
}
/*Never reach this, at least the screen has to be a style*/
return NULL;
#if LV_OBJ_GROUP != 0
if(obj->group_p != NULL) {
if(lv_group_get_focused(obj->group_p) == obj) {
style_act = lv_group_mod_style(obj->group_p, style_act);
}
}
#endif
return style_act;
}
/*-----------------
@ -1395,6 +1418,18 @@ void * lv_obj_get_free_p(lv_obj_t * obj)
}
#endif
#if LV_OBJ_GROUP != 0
/**
* Get the group of the object
* @param obj pointer to an object
* @return the pointer to group of the object
*/
void * lv_obj_get_group(lv_obj_t * obj)
{
return obj->group_p;
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
@ -1523,13 +1558,16 @@ static void lv_obj_del_child(lv_obj_t * obj)
/*Remove the animations from this object*/
anim_del(obj, NULL);
/*Delete from the group*/
#if LV_OBJ_GROUP != 0
if(obj->group_p != NULL) lv_group_rem_obj(obj);
#endif
/*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj);
ll_rem(&(par->child_ll), obj);
/* All children deleted.
* Now clean up the object specific data*/
/* Clean up the object specific data*/
obj->signal_f(obj, LV_SIGNAL_CLEANUP, NULL);
/*Delete the base objects*/

View File

@ -72,19 +72,27 @@ typedef bool (* lv_design_f_t) (struct __LV_OBJ_T * obj, const area_t * mask_p,
typedef enum
{
/*General signals*/
LV_SIGNAL_CLEANUP,
LV_SIGNAL_CHILD_CHG,
LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE,
/*Display input related*/
LV_SIGNAL_PRESSED,
LV_SIGNAL_PRESSING,
LV_SIGNAL_PRESSING,
LV_SIGNAL_PRESS_LOST,
LV_SIGNAL_RELEASED,
LV_SIGNAL_LONG_PRESS,
LV_SIGNAL_LONG_PRESS_REP,
LV_SIGNAL_DRAG_BEGIN,
LV_SIGNAL_DRAG_END,
LV_SIGNAL_CHILD_CHG,
LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE,
LV_SIGNAL_DRAG_END,
/*Group related*/
LV_SIGNAL_FOCUS,
LV_SIGNAL_DEFOCUS,
LV_SIGNAL_CONTROLL,
}lv_signal_t;
typedef bool (* lv_signal_f_t) (struct __LV_OBJ_T * obj, lv_signal_t sign, void * param);
@ -106,6 +114,8 @@ typedef struct __LV_OBJ_T
void * free_p; /*Application specific pointer (set it freely)*/
#endif
void * group_p; /*Pointer to the group of the object*/
/*Attributes and states*/
uint8_t click_en :1; /*1: Can be pressed by a display input device*/
uint8_t drag_en :1; /*1: Enable the dragging*/
@ -159,13 +169,6 @@ typedef enum
LV_ALIGN_OUT_RIGHT_BOTTOM,
}lv_align_t;
typedef struct
{
color_t color;
opa_t opa;
}lv_objs_t;
typedef enum
{
LV_ANIM_NONE = 0,
@ -473,6 +476,7 @@ void lv_obj_set_free_num(lv_obj_t * obj, uint8_t free_num);
*/
void lv_obj_set_free_p(lv_obj_t * obj, void * free_p);
#endif
/**
* Animate an object
* @param obj pointer to an object to animate
@ -665,6 +669,14 @@ uint8_t lv_obj_get_free_num(lv_obj_t * obj);
void * lv_obj_get_free_p(lv_obj_t * obj);
#endif
#if LV_OBJ_GROUP != 0
/**
* Get the group of the object
* @param obj pointer to an object
* @return the pointer to group of the object
*/
void * lv_obj_get_group(lv_obj_t * obj);
#endif
/**********************
* MACROS
**********************/

View File

@ -10,11 +10,11 @@
#include "lv_conf.h"
#if USE_LV_BTN != 0
#include "lvgl/lv_obj/lv_obj.h"
#include "lv_btn.h"
#include "../lv_obj/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/area.h"
#include "misc/gfx/color.h"
#include "../lv_draw/lv_draw.h"
#include "lv_btn.h"
#include <stdbool.h>
#include <string.h>
@ -185,6 +185,31 @@ bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
if(ext->lpr_rep_action != NULL && state != LV_BTN_STATE_INA) {
valid = ext->lpr_rep_action(btn, param);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_REL);
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
} else if(c == LV_GROUP_KEY_ENTER) {
if(lv_btn_get_tgl(btn) != false) {
lv_btn_state_t state = lv_btn_get_state(btn);
if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TPR);
else if(state == LV_BTN_STATE_TREL) lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(state == LV_BTN_STATE_TPR) lv_btn_set_state(btn, LV_BTN_STATE_PR);
}
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
valid = ext->rel_action(btn, param);
}
}
}
}
@ -321,6 +346,50 @@ bool lv_btn_get_tgl(lv_obj_t * btn)
return ext->tgl != 0 ? true : false;
}
/**
* Get the release action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->rel_action;
}
/**
* Get the press action of a button
* @param btn pointer to a button object
* @return pointer to the press action function
*/
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->pr_action;
}
/**
* Get the long press action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->lpr_action;
}
/**
* Get the long press repeat action of a button
* @param btn pointer to a button object
* @return pointer to the long press repeat action function
*/
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn)
{
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
return ext->lpr_rep_action;
}
/**
* Get the style of a button in a given state
* @param btn pointer to a button object

View File

@ -148,6 +148,32 @@ lv_btn_state_t lv_btn_get_state(lv_obj_t * btn);
*/
bool lv_btn_get_tgl(lv_obj_t * btn);
/**
* Get the release action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn);
/**
* Get the press action of a button
* @param btn pointer to a button object
* @return pointer to the press action function
*/
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn);
/**
* Get the long press action of a button
* @param btn pointer to a button object
* @return pointer to the release action function
*/
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn);
/**
* Get the long press repeat action of a button
* @param btn pointer to a button object
* @return pointer to the long press repeat action function
*/
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn);
/**
* Get the style of a button in a given state
* @param btn pointer to a button object

View File

@ -10,9 +10,10 @@
#if USE_LV_BTNM != 0
#include "lv_btnm.h"
#include "misc/gfx/text.h"
#include "../lv_obj/lv_group.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_obj/lv_refr.h"
#include "misc/gfx/text.h"
/*********************
* DEFINES
@ -29,6 +30,7 @@
static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_t mode);
static uint8_t lv_btnm_get_width_unit(const char * btn_str);
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p);
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id);
static void lv_btnm_create_btns(lv_obj_t * btnm, const char ** map);
/**********************
@ -155,18 +157,8 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
}
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_LONG_PRESS_REP) {
if(ext->cb != NULL && ext->btn_pr != LV_BTNM_PR_NONE) {
uint16_t txt_i = 0;
uint16_t btn_i = 0;
/* Search the text of ext->btn_pr the buttons text in the map
* Skip "\n"-s*/
while(btn_i != ext->btn_pr) {
btn_i ++;
txt_i ++;
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
}
ext->cb(btnm, txt_i);
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
}
if(sign == LV_SIGNAL_RELEASED && ext->btn_pr != LV_BTNM_PR_NONE) {
@ -181,11 +173,30 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
ext->btn_pr = LV_BTNM_PR_NONE;
}
}
else if(sign == LV_SIGNAL_PRESS_LOST) {
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
ext->btn_pr = LV_BTNM_PR_NONE;
lv_obj_inv(btnm);
} else if(sign == LV_SIGNAL_FOCUS) {
ext->btn_pr = 0;
lv_obj_inv(btnm);
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
else ext->btn_pr++;
if(ext->btn_pr >= ext->btn_cnt - 1) ext->btn_pr = ext->btn_cnt - 1;
lv_obj_inv(btnm);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
if(ext->btn_pr > 0) ext->btn_pr--;
lv_obj_inv(btnm);
} else if(c == LV_GROUP_KEY_ENTER) {
if(ext->cb != NULL) {
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
}
}
}
}
@ -441,8 +452,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
txt_i ++;
}
}
return true;
}
@ -486,6 +495,12 @@ static uint8_t lv_btnm_get_width_unit(const char * btn_str)
return 1;
}
/**
* Gives the button id of a button under a given point
* @param btnm pointer to a button matrix object
* @param p a point with absolute coordinates
* @return the id of the button or LV_BTNM_PR_NONE.
*/
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
{
area_t btnm_cords;
@ -510,5 +525,33 @@ static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
return i;
}
/**
* Get the text of a button
* @param btnm pointer to a button matrix object
* @param btn_id button id
* @return text id in ext->map_p or LV_BTNM_PR_NONE if 'btn_id' was invalid
*/
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id)
{
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
if(btn_id > ext->btn_cnt) return LV_BTNM_PR_NONE;
uint16_t txt_i = 0;
uint16_t btn_i = 0;
/* Search the text of ext->btn_pr the buttons text in the map
* Skip "\n"-s*/
while(btn_i != btn_id) {
btn_i ++;
txt_i ++;
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
}
if(btn_i == ext->btn_cnt) return LV_BTNM_PR_NONE;
return txt_i;
}
#endif

View File

@ -10,6 +10,7 @@
#if USE_LV_CB != 0
#include "lv_cb.h"
#include "../lv_obj/lv_group.h"
/*********************
* DEFINES
@ -23,11 +24,14 @@
* STATIC PROTOTYPES
**********************/
static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mode);
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode);
/**********************
* STATIC VARIABLES
**********************/
static lv_design_f_t ancestor_design_f;
static lv_design_f_t ancestor_bg_design_f;
static lv_design_f_t ancestor_bullet_design_f;
/**********************
* MACROS
**********************/
@ -57,7 +61,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
ext->bullet = NULL;
ext->label = NULL;
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_cb);
if(ancestor_bg_design_f == NULL) ancestor_bg_design_f = lv_obj_get_design_f(new_cb);
lv_obj_set_signal_f(new_cb, lv_cb_signal);
lv_obj_set_design_f(new_cb, lv_cb_design);
@ -65,6 +69,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
/*Init the new checkbox object*/
if(copy == NULL) {
ext->bullet = lv_btn_create(new_cb, NULL);
if(ancestor_bullet_design_f == NULL) ancestor_bullet_design_f = lv_obj_get_design_f(ext->bullet);
lv_btn_set_styles(new_cb, lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
lv_style_get(LV_STYLE_TRANSP, NULL));
@ -72,6 +77,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
lv_cont_set_fit(new_cb, true, true);
lv_btn_set_tgl(new_cb, true);
lv_obj_set_design_f(ext->bullet, lv_bullet_design);
lv_obj_set_click(ext->bullet, false);
lv_btn_set_styles(ext->bullet, lv_style_get(LV_STYLE_PRETTY, NULL), lv_style_get(LV_STYLE_PRETTY_COLOR, NULL),
lv_style_get(LV_STYLE_BTN_TREL, NULL), lv_style_get(LV_STYLE_BTN_TPR, NULL),
@ -114,11 +120,17 @@ bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
if(valid != false) {
if(sign == LV_SIGNAL_STYLE_CHG) {
lv_obj_set_size(ext->bullet, font_get_height(style->font), font_get_height(style->font));
}
if(sign == LV_SIGNAL_PRESSED ||
} else if(sign == LV_SIGNAL_PRESSED ||
sign == LV_SIGNAL_RELEASED ||
sign == LV_SIGNAL_PRESS_LOST) {
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP ||
c == LV_GROUP_KEY_ENTER) {
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
}
}
}
@ -186,19 +198,62 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo
{
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return ancestor_design_f(cb, mask, mode);
return ancestor_bg_design_f(cb, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {
lv_cb_ext_t * cb_ext = lv_obj_get_ext(cb);
lv_btn_ext_t * bullet_ext = lv_obj_get_ext(cb_ext->bullet);
/*Be sure he state of the bullet is the same as the parent button*/
/*Be sure the state of the bullet is the same as the parent button*/
bullet_ext->state = cb_ext->bg_btn.state;
return ancestor_design_f(cb, mask, mode);
return ancestor_bg_design_f(cb, mask, mode);
} else {
return ancestor_bg_design_f(cb, mask, mode);
}
/*Draw the object*/
return true;
}
/**
* Handle the drawing related tasks of the check boxes
* @param bullet pointer to an object
* @param mask the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return true/false, depends on 'mode'
*/
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
return ancestor_bullet_design_f(bullet, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
#if LV_OBJ_GROUP != 0
/* If the check box is the active in a group and
* the background is not visible (transparent or empty)
* then activate the style of the bullet*/
lv_style_t * style_ori = lv_obj_get_style(bullet);
lv_obj_t * bg = lv_obj_get_parent(bullet);
lv_style_t * style_page = lv_obj_get_style(bg);
lv_group_t * g = lv_obj_get_group(bg);
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
if(lv_group_get_focused(g) == bg) {
lv_style_t * style_mod;
style_mod = lv_group_mod_style(g, style_ori);
bullet->style_p = style_mod; /*Temporally change the style to the activated */
}
}
#endif
ancestor_bullet_design_f(bullet, mask, mode);
#if LV_OBJ_GROUP != 0
bullet->style_p = style_ori; /*Revert the style*/
#endif
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_bullet_design_f(bullet, mask, mode);
}
return true;
}

View File

@ -13,6 +13,7 @@
#include "lv_ddlist.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/anim.h"
#include "../lv_obj/lv_group.h"
/*********************
* DEFINES
@ -70,6 +71,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
ext->opened = 0;
ext->auto_size = 0;
ext->sel_opt = 0;
ext->num_opt = 0;
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);
@ -83,7 +85,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
if(copy == NULL) {
lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
lv_obj_set_drag(scrl, false);
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
lv_cont_set_fit(scrl, true, true);
ext->opt_label = lv_label_create(new_ddlist, NULL);
lv_cont_set_fit(new_ddlist, true, false);
@ -129,7 +132,44 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
lv_ddlist_refr_size(ddlist, 0);
}
} else if(sign == LV_SIGNAL_FOCUS) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
if(ext->opened == false) {
ext->opened = true;
lv_ddlist_refr_size(ddlist, true);
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
if(ext->opened != false) {
ext->opened = false;
lv_ddlist_refr_size(ddlist, true);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
if(ext->sel_opt < ext->num_opt - 1) {
ext->sel_opt ++;
lv_obj_inv(ddlist);
if(ext->cb != NULL) {
ext->cb(ddlist, NULL);
}
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
if(ext->sel_opt > 0) {
ext->sel_opt --;
lv_obj_inv(ddlist);
if(ext->cb != NULL) {
ext->cb(ddlist, NULL);
}
}
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ESC) {
if(ext->opened != false) ext->opened = false;
if(ext->opened == false) ext->opened = true;
lv_ddlist_refr_size(ddlist, true);
}
}
}
return valid;
@ -158,6 +198,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
i++;
}
ext->num_opt = i;
lv_ddlist_refr_size(ddlist, 0);
}
@ -169,6 +211,15 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
/*Count the '\n'-s to determine the number of options*/
ext->num_opt = 0;
uint16_t i;
for(i = 0; options[i] != '\0'; i++) {
if(options[i] == '\n') ext->num_opt++;
}
ext->num_opt++; /*Last option in the at row*/
lv_label_set_text(ext->opt_label, options);
lv_ddlist_refr_size(ddlist, 0);
}
@ -358,7 +409,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_m
rect_area.y1 -= style->line_space / 2;
rect_area.y2 = rect_area.y1 + font_h + style->line_space;
rect_area.x1 = ext->opt_label->cords.x1 - style_page_scrl->hpad;
rect_area.x1 = ext->opt_label->cords.x1 - style->hpad;
rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(ddlist));
lv_draw_rect(&rect_area, mask, ext->style_sel);
@ -417,7 +468,7 @@ static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * disp
}
/**
* Refresh the size of drop down list according its start (open or closed)
* Refresh the size of drop down list according its status (open or closed)
* @param ddlist pointer to a drop down list object
* @param anim_time animations time for open/close [ms]
*/

View File

@ -43,7 +43,8 @@ typedef struct
/*New data for this type */
lv_obj_t * opt_label; /*Label for the options*/
lv_style_t * style_sel; /*Style of the selected option*/
lv_action_t cb; /*Pointer to function to call when an option is slected*/
lv_action_t cb; /*Pointer to function to call when an option is selected*/
uint16_t num_opt; /*Number of options*/
uint16_t sel_opt; /*Index of the current option*/
uint16_t anim_time; /*Open/Close animation time [ms]*/
uint8_t opened :1; /*1: The list is opened*/

View File

@ -13,6 +13,7 @@
#include "misc/math/math_base.h"
#include "lv_label.h"
#include "../lv_obj/lv_obj.h"
#include "../lv_obj/lv_group.h"
#include "misc/gfx/text.h"
#include "misc/gfx/anim.h"
#include "../lv_draw/lv_draw.h"
@ -468,11 +469,9 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
}
x += (font_get_width(font, txt[i]) >> FONT_ANTIALIAS) + style->letter_space;
if(pos->x < x) break;
}
return i;
}
@ -496,11 +495,20 @@ static bool lv_label_design(lv_obj_t * label, const area_t * mask, lv_design_mod
/* A label never covers an area */
if(mode == LV_DESIGN_COVER_CHK) return false;
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*TEST: draw a background for the label*/
area_t cords;
lv_style_t * style = lv_obj_get_style(label);
lv_obj_get_cords(label, &cords);
#if LV_OBJ_GROUP != 0
lv_group_t * g = lv_obj_get_group(label);
if(lv_group_get_focused(g) == label) {
lv_draw_rect(&cords, mask, style);
}
#endif
/*TEST: draw a background for the label*/
//lv_vfill(&label->cords, mask, COLOR_LIME, OPA_COVER);
area_t cords;
lv_obj_get_cords(label, &cords);
lv_label_ext_t * ext = lv_obj_get_ext(label);
txt_flag_t flag = TXT_FLAG_NONE;
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
@ -512,7 +520,7 @@ static bool lv_label_design(lv_obj_t * label, const area_t * mask, lv_design_mod
i++;
}
lv_draw_label(&cords, mask, lv_obj_get_style(label), ext->txt, flag, &ext->offset);
lv_draw_label(&cords, mask, style, ext->txt, flag, &ext->offset);
}

View File

@ -48,7 +48,7 @@ typedef struct
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
point_t offset;
point_t offset; /*Text draw position offset*/
uint8_t static_txt :1; /*Flag to indicate the text is static*/
uint8_t recolor :1; /*Enable in-line letter re-coloring*/
uint8_t expand :1; /*Force expand size when solving line length (used by the library with LV_LABEL_LONG_ROLL)*/

View File

@ -10,13 +10,18 @@
#if USE_LV_LIST != 0
#include "lv_list.h"
#include <lvgl/lv_objx/lv_cont.h>
#include "lvgl/lv_obj/lv_group.h"
#include "lvgl/lv_objx/lv_cont.h"
#include "misc/gfx/anim.h"
#include "misc/math/math_base.h"
/*********************
* DEFINES
*********************/
#define LV_LIST_LAYOUT_DEF LV_CONT_LAYOUT_COL_M
#ifndef LV_LIST_FOCUS_TIME
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
#endif
/**********************
* TYPEDEFS
@ -29,6 +34,8 @@
static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_t mode);
#endif
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn);
/**********************
* STATIC VARIABLES
**********************/
@ -108,6 +115,85 @@ bool lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
/* Include the ancient signal function */
valid = lv_page_signal(list, sign, param);
/* The object can be deleted so check its validity and then
* make the object specific signal handling */
if(valid != false) {
if(sign == LV_SIGNAL_FOCUS) {
/*Get the first button*/
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_list_get_next_btn(list, btn);
while(btn != NULL) {
btn_prev = btn;
btn = lv_list_get_next_btn(list, btn);
}
if(btn_prev != NULL) {
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
/*Get the 'pressed' button*/
lv_obj_t * btn = NULL;
btn = lv_list_get_next_btn(list, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_list_get_next_btn(list, btn);
}
if(btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
/*Get the last pressed button*/
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_list_get_next_btn(list, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn_prev = btn;
btn = lv_list_get_next_btn(list, btn);
}
if(btn_prev != NULL && btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
/*Get the last pressed button*/
lv_obj_t * btn = NULL;
btn = lv_list_get_next_btn(list, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_list_get_next_btn(list, btn);
}
if(btn != NULL) {
lv_obj_t * btn_prev = lv_list_get_next_btn(list, btn);
if(btn_prev != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
}
}
} else if(c == LV_GROUP_KEY_ENTER) {
/*Get the 'pressed' button*/
lv_obj_t * btn = NULL;
btn = lv_list_get_next_btn(list, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_list_get_next_btn(list, btn);
}
if(btn != NULL) {
lv_action_t rel_action;
rel_action = lv_btn_get_rel_action(btn);
if(rel_action != NULL) rel_action(btn, NULL);
}
}
}
}
return valid;
}
@ -175,19 +261,37 @@ void lv_list_up(lv_obj_t * list)
{
/*Search the first list element which 'y' coordinate is below the parent
* and position the list to show this element on the bottom*/
lv_obj_t * h = lv_obj_get_parent(list);
lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_t * e;
lv_obj_t * e_prev = NULL;
e = lv_obj_get_child(list, NULL);
e = lv_list_get_next_btn(list, NULL);
while(e != NULL) {
if(e->cords.y2 <= h->cords.y2) {
if(e_prev != NULL)
lv_obj_set_y(list, lv_obj_get_height(h) -
(lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev)));
if(e->cords.y2 <= list->cords.y2) {
if(e_prev != NULL) {
cord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
#if LV_LIST_FOCUS_TIME == 0
lv_obj_set_y(scrl, new_y);
#else
anim_t a;
a.var = scrl;
a.start = lv_obj_get_y(scrl);
a.end = new_y;
a.fp = (anim_fp_t)lv_obj_set_y;
a.path = anim_get_path(ANIM_PATH_LIN);
a.end_cb = NULL;
a.act_time = 0;
a.time = LV_LIST_FOCUS_TIME;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
anim_create(&a);
#endif
}
break;
}
e_prev = e;
e = lv_obj_get_child(list, e);
e = lv_list_get_next_btn(list, e);
}
}
@ -199,19 +303,36 @@ void lv_list_down(lv_obj_t * list)
{
/*Search the first list element which 'y' coordinate is above the parent
* and position the list to show this element on the top*/
lv_obj_t * h = lv_obj_get_parent(list);
lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_t * e;
e = lv_obj_get_child(list, NULL);
e = lv_list_get_next_btn(list, NULL);
while(e != NULL) {
if(e->cords.y1 < h->cords.y1) {
lv_obj_set_y(list, -lv_obj_get_y(e));
if(e->cords.y1 < list->cords.y1) {
cord_t new_y = -lv_obj_get_y(e);
#if LV_LIST_FOCUS_TIME == 0
lv_obj_set_y(scrl, new_y);
#else
anim_t a;
a.var = scrl;
a.start = lv_obj_get_y(scrl);
a.end = new_y;
a.fp = (anim_fp_t)lv_obj_set_y;
a.path = anim_get_path(ANIM_PATH_LIN);
a.end_cb = NULL;
a.act_time = 0;
a.time = LV_LIST_FOCUS_TIME;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
anim_create(&a);
#endif
break;
}
e = lv_obj_get_child(list, e);
e = lv_list_get_next_btn(list, e);
}
}
/*=====================
* Setter functions
*====================*/
@ -236,8 +357,9 @@ void lv_list_set_sb_out(lv_obj_t * list, bool out)
*/
void lv_list_set_element_text_roll(lv_obj_t * liste, bool en)
{
/*The last child is the label*/
lv_obj_t * label = lv_obj_get_child(liste, NULL);
lv_obj_t * label = lv_list_get_element_label(liste);
if(label == NULL) return;
if(en == false) {
lv_label_set_long_mode(label, LV_LABEL_LONG_DOTS);
} else {
@ -269,12 +391,11 @@ void lv_list_set_styles_btn(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr,
ext->styles_btn[LV_BTN_STATE_TPR] = tpr;
ext->styles_btn[LV_BTN_STATE_INA] = ina;
lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
while(liste != NULL)
{
lv_btn_set_styles(liste, rel, pr, trel, tpr, ina);
liste = lv_obj_get_child(scrl, liste);
liste = lv_list_get_next_btn(list, liste);
}
}
@ -290,16 +411,14 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
ext->style_img = style;
lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
lv_obj_t * img;
while(liste != NULL)
{
img = lv_obj_get_child(liste, NULL); /*Now img = the label*/
img = lv_obj_get_child(liste, img); /*Now img = the image (if ULL then no image) */
img = lv_list_get_element_img(liste);
if(img != NULL) lv_obj_set_style(img, style);
liste = lv_obj_get_child(scrl, liste);
liste = lv_list_get_next_btn(list, liste);
}
}
@ -314,11 +433,47 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
*/
const char * lv_list_get_element_text(lv_obj_t * liste)
{
/*The last child is the label*/
lv_obj_t * label = lv_obj_get_child(liste, NULL);
lv_obj_t * label = lv_list_get_element_label(liste);
if(label == NULL) return "";
return lv_label_get_text(label);
}
/**
* Get the label object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the label from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste)
{
lv_obj_t * label = lv_obj_get_child(liste, NULL);
if(label == NULL) return NULL;
while(label->signal_f != lv_label_signal) {
label = lv_obj_get_child(liste, NULL);
if(label == NULL) break;
}
return label;
}
/**
* Get the image object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the image from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste)
{
lv_obj_t * img = lv_obj_get_child(liste, NULL);
if(img == NULL) return NULL;
while(img->signal_f != lv_img_signal) {
img = lv_obj_get_child(liste, NULL);
if(img == NULL) break;
}
return img;
}
/**
* Get the scroll bar outside attribute
* @param list pointer to list object
@ -388,4 +543,29 @@ static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_
}
#endif
/**
* Get the next button from list
* @param list pointer to a list object
* @param prev_btn pointer to button. Search the next after it.
* @return pointer to the next button or NULL
*/
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn)
{
/* Not a good practice but user can add/create objects to the lists manually.
* When getting the next button try to be sure that it is at least a button */
lv_obj_t * btn ;
lv_obj_t * scrl = lv_page_get_scrl(list);
btn = lv_obj_get_child(scrl, prev_btn);
if(btn == NULL) return NULL;
while(btn->signal_f != lv_btn_signal) {
btn = lv_obj_get_child(scrl, prev_btn);
if(btn == NULL) break;
}
return btn;
}
#endif

View File

@ -141,6 +141,20 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style);
*/
const char * lv_list_get_element_text(lv_obj_t * liste);
/**
* Get the label object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the label from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste);
/**
* Get the image object from a list element
* @param liste pointer to a list element (button)
* @return pointer to the image from the list element or NULL if not found
*/
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste);
/**
* Get the scroll bar outside attribute
* @param list pointer to list object

View File

@ -11,6 +11,7 @@
#if USE_LV_MBOX != 0
#include "lv_mbox.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/gfx/anim.h"
#include "misc/math/math_base.h"
@ -132,13 +133,11 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
area_get_height(param) != lv_obj_get_height(mbox)) {
lv_mbox_realign(mbox);
}
}
else if(sign == LV_SIGNAL_LONG_PRESS) {
} else if(sign == LV_SIGNAL_LONG_PRESS) {
lv_mbox_start_auto_close(mbox, 0);
lv_dispi_wait_release(param);
valid = false;
}
else if(sign == LV_SIGNAL_STYLE_CHG) {
} else if(sign == LV_SIGNAL_STYLE_CHG) {
/*Refresh all the buttons*/
if(ext->btnh != NULL) {
lv_obj_t * btn;
@ -150,6 +149,90 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
btn = lv_obj_get_child(ext->btnh, btn);
}
}
} else if(sign == LV_SIGNAL_FOCUS) {
/*Get the first button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
btn_prev = btn;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn_prev != NULL) {
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
/*Get the 'pressed' button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
}
}
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_mbox_ext_t * ext = lv_obj_get_ext(mbox);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
/*Get the last pressed button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
lv_obj_t * btn_prev = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn_prev = btn;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn_prev != NULL && btn != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
/*Get the last pressed button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn);
if(btn_prev != NULL) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
}
}
}
} else if(c == LV_GROUP_KEY_ENTER) {
/*Get the 'pressed' button*/
if(ext->btnh != NULL) {
lv_obj_t * btn = NULL;
btn = lv_obj_get_child(ext->btnh, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_obj_get_child(ext->btnh, btn);
}
if(btn != NULL) {
lv_action_t rel_action;
rel_action = lv_btn_get_rel_action(btn);
if(rel_action != NULL) rel_action(btn, NULL);
}
}
}
}
}

View File

@ -10,6 +10,7 @@
#if USE_LV_PAGE != 0
#include "misc/math/math_base.h"
#include "../lv_obj/lv_group.h"
#include "../lv_objx/lv_page.h"
#include "../lv_objx/lv_cont.h"
#include "../lv_draw/lv_draw.h"
@ -28,13 +29,15 @@
* STATIC PROTOTYPES
**********************/
static void lv_page_sb_refresh(lv_obj_t * main);
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode);
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param);
/**********************
* STATIC VARIABLES
**********************/
static lv_design_f_t ancestor_design_f;
static lv_design_f_t ancestor_page_design_f;
static lv_design_f_t ancestor_scrl_design_f;
/**********************
* MACROS
@ -72,18 +75,20 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy)
ext->sb_width = LV_DPI / 8; /*Will be modified later*/
ext->sb_mode = LV_PAGE_SB_MODE_ON;
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_page);
if(ancestor_page_design_f == NULL) ancestor_page_design_f = lv_obj_get_design_f(new_page);
/*Init the new page object*/
if(copy == NULL) {
lv_style_t * style = lv_style_get(LV_STYLE_PRETTY_COLOR, NULL);
ext->scrl = lv_cont_create(new_page, NULL);
if(ancestor_scrl_design_f == NULL) ancestor_scrl_design_f = lv_obj_get_design_f(ext->scrl);
lv_obj_set_signal_f(ext->scrl, lv_scrl_signal);
lv_obj_set_drag(ext->scrl, true);
lv_obj_set_drag_throw(ext->scrl, true);
lv_obj_set_protect(ext->scrl, LV_PROTECT_PARENT);
lv_cont_set_fit(ext->scrl, true, true);
lv_cont_set_fit(ext->scrl, false, true);
lv_obj_set_style(ext->scrl, lv_style_get(LV_STYLE_PRETTY, NULL));
lv_obj_set_design_f(ext->scrl, lv_scrl_design);
lv_page_set_sb_width(new_page, style->hpad);
lv_page_set_sb_mode(new_page, ext->sb_mode);
@ -138,60 +143,60 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
if(obj_valid != false) {
lv_page_ext_t * ext = lv_obj_get_ext(page);
lv_obj_t * child;
switch(sign) {
case LV_SIGNAL_CHILD_CHG: /*Move children to the scrollable object*/
child = lv_obj_get_child(page, NULL);
while(child != NULL) {
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
lv_obj_t * tmp = child;
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
lv_obj_set_parent(tmp, ext->scrl);
} else {
child = lv_obj_get_child(page, child);
}
}
break;
case LV_SIGNAL_STYLE_CHG:
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
ext->sbh_draw = 1;
ext->sbv_draw = 1;
} else {
ext->sbh_draw = 0;
ext->sbv_draw = 0;
}
lv_page_sb_refresh(page);
break;
case LV_SIGNAL_CORD_CHG:
/*Refresh the scrollbar and notify the scrl if the size is changed*/
if(ext->scrl != NULL &&
(lv_obj_get_width(page) != area_get_width(param) ||
lv_obj_get_height(page) != area_get_height(param))) {
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
/*The scrolbars are important olny if they are visible now*/
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
lv_page_sb_refresh(page);
}
break;
case LV_SIGNAL_PRESSED:
if(ext->pr_action != NULL) {
ext->pr_action(page, param);
if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the scrollable object*/
child = lv_obj_get_child(page, NULL);
while(child != NULL) {
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
lv_obj_t * tmp = child;
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
lv_obj_set_parent(tmp, ext->scrl);
} else {
child = lv_obj_get_child(page, child);
}
break;
case LV_SIGNAL_RELEASED:
if(lv_dispi_is_dragging(param) == false) {
if(ext->rel_action != NULL) {
ext->rel_action(page, param);
}
}
} else if(sign == LV_SIGNAL_STYLE_CHG) {
lv_style_t * style = lv_obj_get_style(page);
if(lv_cont_get_hfit(ext->scrl) == false) {
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
}
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
ext->sbh_draw = 1;
ext->sbv_draw = 1;
} else {
ext->sbh_draw = 0;
ext->sbv_draw = 0;
}
lv_page_sb_refresh(page);
} else if(sign == LV_SIGNAL_CORD_CHG) {
lv_style_t * style = lv_obj_get_style(page);
/*Refresh the scrollbar and notify the scrl if the size is changed*/
if(ext->scrl != NULL &&
(lv_obj_get_width(page) != area_get_width(param) ||
lv_obj_get_height(page) != area_get_height(param))) {
if(lv_cont_get_hfit(ext->scrl) == false) {
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
}
break;
default:
break;
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
/*The scrollbars are important olny if they are visible now*/
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
lv_page_sb_refresh(page);
}
} else if(sign == LV_SIGNAL_PRESSED) {
if(ext->pr_action != NULL) {
ext->pr_action(page, param);
}
} else if(sign == LV_SIGNAL_RELEASED) {
if(lv_dispi_is_dragging(param) == false) {
if(ext->rel_action != NULL) {
ext->rel_action(page, param);
}
}
}
}
@ -215,118 +220,112 @@ static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param)
* make the object specific signal handling */
if(obj_valid != false) {
cord_t new_x;
cord_t new_y;
bool refr_x = false;
bool refr_y = false;
area_t page_cords;
area_t obj_cords;
lv_obj_t * page = lv_obj_get_parent(scrl);
lv_style_t * page_style = lv_obj_get_style(page);
lv_page_ext_t * page_ext = lv_obj_get_ext(page);
cord_t hpad = page_style->hpad;
cord_t vpad = page_style->vpad;
switch(sign) {
case LV_SIGNAL_CORD_CHG:
new_x = lv_obj_get_x(scrl);
new_y = lv_obj_get_y(scrl);
lv_obj_get_cords(scrl, &obj_cords);
lv_obj_get_cords(page, &page_cords);
if(sign == LV_SIGNAL_CORD_CHG) {
cord_t new_x;
cord_t new_y;
bool refr_x = false;
bool refr_y = false;
area_t page_cords;
area_t scrl_cords;
cord_t hpad = page_style->hpad;
cord_t vpad = page_style->vpad;
/*scrollable width smaller then page width? -> align to left*/
if(area_get_width(&obj_cords) + 2 * hpad < area_get_width(&page_cords)) {
if(obj_cords.x1 != page_cords.x1 + hpad) {
new_x = hpad;
refr_x = true;
}
} else {
/*The edges of the scrollable can not be in the page (minus hpad) */
if(obj_cords.x2 < page_cords.x2 - hpad) {
new_x = area_get_width(&page_cords) - area_get_width(&obj_cords) - hpad; /* Right align */
refr_x = true;
}
if (obj_cords.x1 > page_cords.x1 + hpad) {
new_x = hpad; /*Left align*/
refr_x = true;
}
new_x = lv_obj_get_x(scrl);
new_y = lv_obj_get_y(scrl);
lv_obj_get_cords(scrl, &scrl_cords);
lv_obj_get_cords(page, &page_cords);
/*scrollable width smaller then page width? -> align to left*/
if(area_get_width(&scrl_cords) + 2 * hpad < area_get_width(&page_cords)) {
if(scrl_cords.x1 != page_cords.x1 + hpad) {
new_x = hpad;
refr_x = true;
}
/*scrollable height smaller then page height? -> align to left*/
if(area_get_height(&obj_cords) + 2 * vpad < area_get_height(&page_cords)) {
if(obj_cords.y1 != page_cords.y1 + vpad) {
new_y = vpad;
refr_y = true;
}
} else {
/*The edges of the scrollable can not be in the page (minus vpad) */
if(obj_cords.y2 < page_cords.y2 - vpad) {
new_y = area_get_height(&page_cords) - area_get_height(&obj_cords) - vpad; /* Bottom align */
refr_y = true;
}
if (obj_cords.y1 > page_cords.y1 + vpad) {
new_y = vpad; /*Top align*/
refr_y = true;
}
} else {
/*The edges of the scrollable can not be in the page (minus hpad) */
if(scrl_cords.x2 < page_cords.x2 - hpad) {
new_x = area_get_width(&page_cords) - area_get_width(&scrl_cords) - hpad; /* Right align */
refr_x = true;
}
if(refr_x != false || refr_y != false) {
lv_obj_set_pos(scrl, new_x, new_y);
if (scrl_cords.x1 > page_cords.x1 + hpad) {
new_x = hpad; /*Left align*/
refr_x = true;
}
}
lv_page_sb_refresh(page);
break;
case LV_SIGNAL_DRAG_BEGIN:
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
page_ext->sbv_draw = 1;
}
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
page_ext->sbh_draw = 1;
}
}
break;
case LV_SIGNAL_DRAG_END:
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
area_t sb_area_tmp;
if(page_ext->sbh_draw != 0) {
area_cpy(&sb_area_tmp, &page_ext->sbh);
sb_area_tmp.x1 += page->cords.x1;
sb_area_tmp.y1 += page->cords.y1;
sb_area_tmp.x2 += page->cords.x2;
sb_area_tmp.y2 += page->cords.y2;
lv_inv_area(&sb_area_tmp);
page_ext->sbh_draw = 0;
}
if(page_ext->sbv_draw != 0) {
area_cpy(&sb_area_tmp, &page_ext->sbv);
sb_area_tmp.x1 += page->cords.x1;
sb_area_tmp.y1 += page->cords.y1;
sb_area_tmp.x2 += page->cords.x2;
sb_area_tmp.y2 += page->cords.y2;
lv_inv_area(&sb_area_tmp);
page_ext->sbv_draw = 0;
}
}
break;
case LV_SIGNAL_PRESSED:
if(page_ext->pr_action != NULL) {
page_ext->pr_action(page, param);
/*scrollable height smaller then page height? -> align to left*/
if(area_get_height(&scrl_cords) + 2 * vpad < area_get_height(&page_cords)) {
if(scrl_cords.y1 != page_cords.y1 + vpad) {
new_y = vpad;
refr_y = true;
}
break;
case LV_SIGNAL_RELEASED:
if(lv_dispi_is_dragging(param) == false) {
if(page_ext->rel_action != NULL) {
page_ext->rel_action(page, param);
}
} else {
/*The edges of the scrollable can not be in the page (minus vpad) */
if(scrl_cords.y2 < page_cords.y2 - vpad) {
new_y = area_get_height(&page_cords) - area_get_height(&scrl_cords) - vpad; /* Bottom align */
refr_y = true;
}
break;
default:
break;
if (scrl_cords.y1 > page_cords.y1 + vpad) {
new_y = vpad; /*Top align*/
refr_y = true;
}
}
if(refr_x != false || refr_y != false) {
lv_obj_set_pos(scrl, new_x, new_y);
}
lv_page_sb_refresh(page);
} else if(sign == LV_SIGNAL_CORD_CHG) {
if(lv_cont_get_hfit(scrl) == false) {
lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->hpad);
}
} else if(sign == LV_SIGNAL_DRAG_BEGIN) {
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
page_ext->sbv_draw = 1;
}
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
page_ext->sbh_draw = 1;
}
}
} else if(sign == LV_SIGNAL_DRAG_END) {
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
area_t sb_area_tmp;
if(page_ext->sbh_draw != 0) {
area_cpy(&sb_area_tmp, &page_ext->sbh);
sb_area_tmp.x1 += page->cords.x1;
sb_area_tmp.y1 += page->cords.y1;
sb_area_tmp.x2 += page->cords.x2;
sb_area_tmp.y2 += page->cords.y2;
lv_inv_area(&sb_area_tmp);
page_ext->sbh_draw = 0;
}
if(page_ext->sbv_draw != 0) {
area_cpy(&sb_area_tmp, &page_ext->sbv);
sb_area_tmp.x1 += page->cords.x1;
sb_area_tmp.y1 += page->cords.y1;
sb_area_tmp.x2 += page->cords.x2;
sb_area_tmp.y2 += page->cords.y2;
lv_inv_area(&sb_area_tmp);
page_ext->sbv_draw = 0;
}
}
}else if(sign == LV_SIGNAL_PRESSED) {
if(page_ext->pr_action != NULL) {
page_ext->pr_action(page, param);
}
} else if(sign == LV_SIGNAL_RELEASED) {
if(lv_dispi_is_dragging(param) == false) {
if(page_ext->rel_action != NULL) {
page_ext->rel_action(page, param);
}
}
}
}
@ -534,41 +533,85 @@ lv_style_t * lv_page_get_style_sb(lv_obj_t * page)
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return true/false, depends on 'mode'
*/
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode)
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
return ancestor_design_f(page, mask, mode);
return ancestor_page_design_f(scrl, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design_f(page, mask, mode);
ancestor_page_design_f(scrl, mask, mode);
} else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/
ancestor_design_f(page, mask, mode);
lv_page_ext_t * ext = lv_obj_get_ext(page);
ancestor_page_design_f(scrl, mask, mode);
lv_page_ext_t * ext = lv_obj_get_ext(scrl);
/*Draw the scrollbars*/
area_t sb_area;
if(ext->sbh_draw != 0) {
/*Convert the relative coordinates to absolute*/
area_cpy(&sb_area, &ext->sbh);
sb_area.x1 += page->cords.x1;
sb_area.y1 += page->cords.y1;
sb_area.x2 += page->cords.x1;
sb_area.y2 += page->cords.y1;
sb_area.x1 += scrl->cords.x1;
sb_area.y1 += scrl->cords.y1;
sb_area.x2 += scrl->cords.x1;
sb_area.y2 += scrl->cords.y1;
lv_draw_rect(&sb_area, mask, ext->style_sb);
}
if(ext->sbv_draw != 0) {
/*Convert the relative coordinates to absolute*/
area_cpy(&sb_area, &ext->sbv);
sb_area.x1 += page->cords.x1;
sb_area.y1 += page->cords.y1;
sb_area.x2 += page->cords.x1;
sb_area.y2 += page->cords.y1;
sb_area.x1 += scrl->cords.x1;
sb_area.y1 += scrl->cords.y1;
sb_area.x2 += scrl->cords.x1;
sb_area.y2 += scrl->cords.y1;
lv_draw_rect(&sb_area, mask, ext->style_sb);
}
}
return true;
}
/**
* Handle the drawing related tasks of the scrollable object
* @param scrl pointer to an object
* @param mask the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return true/false, depends on 'mode'
*/
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
return ancestor_page_design_f(scrl, mask, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
#if LV_OBJ_GROUP != 0
/* If the page is the active in a group and
* the background (page) is not visible (transparent or empty)
* then activate the style of the scrollable*/
lv_style_t * style_ori = lv_obj_get_style(scrl);
lv_obj_t * page = lv_obj_get_parent(scrl);
lv_style_t * style_page = lv_obj_get_style(page);
lv_group_t * g = lv_obj_get_group(page);
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
if(lv_group_get_focused(g) == page) {
lv_style_t * style_mod;
style_mod = lv_group_mod_style(g, style_ori);
scrl->style_p = style_mod; /*Temporally change the style to the activated */
}
}
#endif
ancestor_page_design_f(scrl, mask, mode);
#if LV_OBJ_GROUP != 0
scrl->style_p = style_ori; /*Revert the style*/
#endif
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_page_design_f(scrl, mask, mode);
}
return true;
}
/**
* Refresh the position and size of the scroll bars.

View File

@ -10,6 +10,7 @@
#if USE_LV_SLIDER != 0
#include "lv_slider.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/math/math_base.h"
#include "../lv_draw/lv_draw.h"
@ -52,7 +53,6 @@ static lv_design_f_t ancestor_design_f;
lv_obj_t * lv_slider_create(lv_obj_t * par, lv_obj_t * copy)
{
/*Create the ancestor slider*/
/*TODO modify it to the ancestor create function */
lv_obj_t * new_slider = lv_bar_create(par, copy);
dm_assert(new_slider);
@ -102,7 +102,6 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
bool valid;
/* Include the ancient signal function */
/* TODO update it to the ancestor's signal function*/
valid = lv_bar_signal(slider, sign, param);
/* The object can be deleted so check its validity and then
@ -145,10 +144,19 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
lv_obj_get_height(slider) != area_get_height(param)) {
slider->signal_f(slider, LV_SIGNAL_REFR_EXT_SIZE, NULL);
}
}
else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
cord_t x = MATH_MIN(w, h);
if(slider->ext_size < x) slider->ext_size = x;
} else if(sign == LV_SIGNAL_CONTROLL) {
lv_slider_ext_t * ext = lv_obj_get_ext(slider);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
lv_bar_set_value(slider, lv_bar_get_value(slider) + 1);
if(ext->cb != NULL) ext->cb(slider, NULL);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
lv_bar_set_value(slider, lv_bar_get_value(slider) - 1);
if(ext->cb != NULL) ext->cb(slider, NULL);
}
}
}

View File

@ -11,6 +11,7 @@
#if USE_LV_TA != 0
#include "lv_ta.h"
#include "lvgl/lv_obj/lv_group.h"
#include "misc/gfx/anim.h"
#include "../lv_draw/lv_draw.h"
@ -158,32 +159,37 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
if(valid != false) {
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
lv_style_t * style = lv_obj_get_style(ta);
switch(sign) {
case LV_SIGNAL_CLEANUP:
/* Nothing to clean up.
* (The created label will be deleted automatically) */
break;
case LV_SIGNAL_STYLE_CHG:
if(ext->label) {
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
break;
if(sign == LV_SIGNAL_CLEANUP) {
/* Nothing to clean up.
* (The created label will be deleted automatically) */
} else if(sign == LV_SIGNAL_STYLE_CHG) {
if(ext->label) {
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
} else if(sign == LV_SIGNAL_CORD_CHG) {
/*Set the label width according to the text area width*/
case LV_SIGNAL_CORD_CHG:
if(ext->label != NULL) {
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
break;
default:
break;
}
if(ext->label != NULL) {
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
(style->hpad + style->hpad));
lv_label_set_text(ext->label, NULL);
}
} else if (sign == LV_SIGNAL_CONTROLL) {
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
char c = *((char*)param);
if(c == LV_GROUP_KEY_RIGHT) {
lv_ta_cursor_right(ta);
} else if(c == LV_GROUP_KEY_LEFT) {
lv_ta_cursor_left(ta);
} else if(c == LV_GROUP_KEY_UP) {
lv_ta_cursor_up(ta);
} else if(c == LV_GROUP_KEY_DOWN) {
lv_ta_cursor_down(ta);
}
}
}
return valid;
}

36
lvgl.h
View File

@ -16,23 +16,8 @@ extern "C" {
/*Test misc. module version*/
#include "misc/misc.h"
#define LV_MISC_REQ_MAJOR 4
#define LV_MISC_REQ_MINOR 1
#define LV_MISC_REQ_PATCH 1
#if MISC_VERSION_MAJOR != LV_MISC_REQ_MAJOR /*The version major has to match*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
#if MISC_VERSION_MINOR < LV_MISC_REQ_MINOR /*The version minor has to be the same or greater*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
#if MISC_VERSION_PATCH < LV_MISC_REQ_PATCH /*The version patch has to be the same or greater*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
#include "lv_obj/lv_obj.h"
#include "lv_obj/lv_group.h"
#include "lv_objx/lv_btn.h"
#include "lv_objx/lv_img.h"
#include "lv_objx/lv_label.h"
@ -58,10 +43,27 @@ extern "C" {
/*********************
* DEFINES
*********************/
/*Current version of LittlevGL*/
#define LVGL_VERSION_MAJOR 4
#define LVGL_VERSION_MINOR 1
#define LVGL_VERSION_PATH 0
#define LVGL_VERSION_PATH 1
/*Required misc. library version*/
#define LV_MISC_REQ_MAJOR 4
#define LV_MISC_REQ_MINOR 1
#define LV_MISC_REQ_PATCH 0
#if MISC_VERSION_MAJOR != LV_MISC_REQ_MAJOR /*The version major has to match*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
#if MISC_VERSION_MINOR < LV_MISC_REQ_MINOR /*The version minor has to be the same or greater*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
#if MISC_VERSION_PATCH < LV_MISC_REQ_PATCH /*The version patch has to be the same or greater*/
#error "LV: incompatible misc. module version! See lvgl.h"
#endif
/**********************
* TYPEDEFS