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

lv_ta finished + LV_DESIGN_MODE_DRAW_POST added + bugfixes

This commit is contained in:
Gabor 2016-10-04 09:45:39 +02:00
parent 1a591d4946
commit d9b063d7d6
29 changed files with 934 additions and 488 deletions

View File

@ -10,7 +10,7 @@
* INCLUDES
*********************/
#include "misc/others/color.h"
#include "../lv_misc/2d.h"
#include "../lv_misc/area.h"
#include "../lv_misc/font.h"
/*********************

View File

@ -14,7 +14,7 @@
#if LV_VDB_SIZE != 0
#include "misc/others/color.h"
#include "../lv_misc/2d.h"
#include "../lv_misc/area.h"
#include "../lv_misc/font.h"
/*********************

View File

@ -6,7 +6,7 @@
/*********************
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include "misc/math/math_base.h"
/*********************
@ -49,6 +49,26 @@ void area_set(area_t * area_p, cord_t x1, cord_t y1, cord_t x2, cord_t y2)
area_p->y2 = y2;
}
void area_set_width(area_t * area_p, cord_t w)
{
area_p->x2 = area_p->x1 + w - 1;
}
void area_set_height(area_t * area_p, cord_t h)
{
area_p->y2 = area_p->y1 + h - 1;
}
void area_set_pos(area_t * area_p, cord_t x, cord_t y)
{
cord_t w = area_get_width(area_p);
cord_t h = area_get_height(area_p);
area_p->x1 = x;
area_p->y1 = y;
area_set_width(area_p, w);
area_set_height(area_p, h);
}
/**
* Return with area of an area (x * y)
* @param area_p pointer to an area

View File

@ -1,5 +1,5 @@
/**
* @file 2d.h
* @file area.h
*
*/
@ -57,6 +57,9 @@ static inline cord_t area_get_height(const area_t * area_p)
}
void area_set(area_t * area_p, cord_t x1, cord_t y1, cord_t x2, cord_t y2);
void area_set_width(area_t * area_p, cord_t w);
void area_set_height(area_t * area_p, cord_t h);
void area_set_pos(area_t * area_p, cord_t x, cord_t y);
uint32_t area_get_size(const area_t * area_p);
bool area_union(area_t * res_p, const area_t * a1_p, const area_t * a2_p);
void area_join(area_t * a_res_p, const area_t * a1_p, const area_t * a2_p);

View File

@ -8,7 +8,7 @@
/*********************
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
/*********************
* DEFINES

View File

@ -10,7 +10,7 @@
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include <stddef.h>
/*********************

View File

@ -72,6 +72,10 @@ uint16_t txt_get_next_line(const char * txt, const font_t * font_p,
while(txt[i] == ' ') i++;
/* Do not let to return without doing nothing.
* Find at least one character */
if(i == 0) i++;
return i;
}
/*If this char still can fit to this line then check if

View File

@ -10,7 +10,7 @@
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include <stdbool.h>
#include "font.h"

View File

@ -394,18 +394,15 @@ void lv_obj_set_parent(lv_obj_t* obj_dp, lv_obj_t* parent_dp)
old_pos.y = lv_obj_get_y(obj_dp);
ll_chg_list(&obj_dp->par_dp->child_ll, &parent_dp->child_ll, obj_dp);
obj_dp->par_dp = parent_dp;
lv_obj_set_pos(obj_dp, old_pos.x, old_pos.y);
/*Notify the original parent because one of its children is lost*/
obj_dp->par_dp->signal_f(obj_dp->par_dp, LV_SIGNAL_CHILD_CHG, NULL);
obj_dp->par_dp = parent_dp;
lv_obj_set_pos(obj_dp, old_pos.x, old_pos.y);
/*Notify the new parent about the child*/
parent_dp->signal_f(parent_dp, LV_SIGNAL_CHILD_CHG, obj_dp);
lv_obj_inv(obj_dp);
}
@ -1342,20 +1339,19 @@ static bool lv_obj_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mo
bool cover;
cover = area_is_in(mask_p, &obj_dp->cords);
return cover;
}
} else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_objs_t * objs_p = lv_obj_get_style(obj_dp);
lv_objs_t * objs_p = lv_obj_get_style(obj_dp);
opa_t opa = lv_obj_get_opa(obj_dp);
color_t color = objs_p->color;
opa_t opa = lv_obj_get_opa(obj_dp);
color_t color = objs_p->color;
/*Simply draw a rectangle*/
/*Simply draw a rectangle*/
#if LV_VDB_SIZE == 0
lv_rfill(&obj_dp->cords, mask_p, color, opa);
lv_rfill(&obj_dp->cords, mask_p, color, opa);
#else
lv_vfill(&obj_dp->cords, mask_p, color, opa);
lv_vfill(&obj_dp->cords, mask_p, color, opa);
#endif
}
return true;
}

View File

@ -9,7 +9,7 @@
/*********************
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include <stddef.h>
#include <stdbool.h>
#include "misc/mem/dyn_mem.h"
@ -54,7 +54,8 @@ struct __LV_OBJ_T;
typedef enum
{
LV_DESIGN_DRAW,
LV_DESIGN_DRAW_MAIN,
LV_DESIGN_DRAW_POST,
LV_DESIGN_COVER_CHK,
}lv_design_mode_t;

View File

@ -399,7 +399,7 @@ static void lv_refr_obj(lv_obj_t* obj_dp, const area_t * mask_ori_p)
/* Redraw the object */
if(obj_dp->opa != OPA_TRANSP && LV_SA(obj_dp, lv_objs_t)->transp == 0) {
obj_dp->design_f(obj_dp, &mask_parent, LV_DESIGN_DRAW);
obj_dp->design_f(obj_dp, &mask_parent, LV_DESIGN_DRAW_MAIN);
}
area_t mask_child; /*Mask from obj_dp and its child*/
@ -416,5 +416,10 @@ static void lv_refr_obj(lv_obj_t* obj_dp, const area_t * mask_ori_p)
lv_refr_obj(child_p, &mask_child);
}
}
/* If all the children are redrawn call make 'post draw' design */
if(obj_dp->opa != OPA_TRANSP && LV_SA(obj_dp, lv_objs_t)->transp == 0) {
obj_dp->design_f(obj_dp, &mask_parent, LV_DESIGN_DRAW_POST);
}
}
}

View File

@ -14,7 +14,7 @@
#if LV_VDB_SIZE != 0
#include "misc/others/color.h"
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include "../lv_misc/font.h"
/*********************

View File

@ -368,6 +368,7 @@ lv_btns_t * lv_btns_get(lv_btns_builtin_t style, lv_btns_t * copy_p)
* @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_btn_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -392,19 +393,18 @@ static bool lv_btn_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mod
if(area_is_in(mask_p, &area_tmp) == true) return true;
return false;
} else if(mode == LV_DESIGN_DRAW_MAIN) {
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
lv_rects_t rects_tmp;
lv_btn_style_load(obj_dp, &rects_tmp);
/*Draw the rectangle*/
lv_draw_rect(&area, mask_p, &rects_tmp, opa);
}
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
lv_rects_t rects_tmp;
lv_btn_style_load(obj_dp, &rects_tmp);
/*Draw the rectangle*/
lv_draw_rect(&area, mask_p, &rects_tmp, opa);
return true;
}

View File

@ -319,6 +319,7 @@ lv_btnm_callback_t lv_btnm_get_cb(lv_obj_t * obj_dp)
* @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_btnm_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)

View File

@ -263,6 +263,7 @@ lv_cbs_t * lv_cbs_get(lv_cbs_builtin_t style, lv_cbs_t * copy_p)
* @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_cb_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)

View File

@ -354,6 +354,7 @@ uint16_t lv_chart_get_pnum(lv_obj_t * obj_dp)
* @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_chart_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -361,31 +362,30 @@ static bool lv_chart_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_m
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return ancestor_design_fp(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the rectangle ancient*/
ancestor_design_fp(obj_dp, mask_p, mode);
/*Draw the object*/
lv_chart_ext_t * ext_dp = lv_obj_get_ext(obj_dp);
lv_chart_draw_div(obj_dp, mask_p);
switch(ext_dp->type) {
case LV_CHART_LINE:
lv_chart_draw_lines(obj_dp, mask_p);
break;
case LV_CHART_COL:
lv_chart_draw_cols(obj_dp, mask_p);
break;
case LV_CHART_POINT:
lv_chart_draw_points(obj_dp, mask_p);
break;
default:
break;
}
}
/*Draw the rectangle ancient*/
ancestor_design_fp(obj_dp, mask_p, mode);
/*Draw the object*/
lv_chart_ext_t * ext_dp = lv_obj_get_ext(obj_dp);
lv_chart_draw_div(obj_dp, mask_p);
switch(ext_dp->type) {
case LV_CHART_LINE:
lv_chart_draw_lines(obj_dp, mask_p);
break;
case LV_CHART_COL:
lv_chart_draw_cols(obj_dp, mask_p);
break;
case LV_CHART_POINT:
lv_chart_draw_points(obj_dp, mask_p);
break;
default:
break;
}
return true;
}

View File

@ -256,6 +256,7 @@ bool lv_img_get_auto_size(lv_obj_t* obj_dp)
* @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_img_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -270,24 +271,25 @@ static bool lv_img_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mod
return cover;
}
else return false;
} else if(mode == LV_DESIGN_DRAW_MAIN) {
area_t cords;
lv_obj_get_cords(obj_dp, &cords);
opa_t opa = lv_obj_get_opa(obj_dp);
area_t cords_tmp;
cords_tmp.y1 = cords.y1;
cords_tmp.y2 = cords.y1 + ext_p->h - 1;
for(; cords_tmp.y1 < cords.y2; cords_tmp.y1 += ext_p->h, cords_tmp.y2 += ext_p->h) {
cords_tmp.x1 = cords.x1;
cords_tmp.x2 = cords.x1 + ext_p->w - 1;
for(; cords_tmp.x1 < cords.x2; cords_tmp.x1 += ext_p->w, cords_tmp.x2 += ext_p->w) {
lv_draw_img(&cords_tmp, mask_p, imgs_p, opa, ext_p->fn_dp);
}
}
}
area_t cords;
lv_obj_get_cords(obj_dp, &cords);
opa_t opa = lv_obj_get_opa(obj_dp);
area_t cords_tmp;
cords_tmp.y1 = cords.y1;
cords_tmp.y2 = cords.y1 + ext_p->h - 1;
for(; cords_tmp.y1 < cords.y2; cords_tmp.y1 += ext_p->h, cords_tmp.y2 += ext_p->h) {
cords_tmp.x1 = cords.x1;
cords_tmp.x2 = cords.x1 + ext_p->w - 1;
for(; cords_tmp.x1 < cords.x2; cords_tmp.x1 += ext_p->w, cords_tmp.x2 += ext_p->w) {
lv_draw_img(&cords_tmp, mask_p, imgs_p, opa, ext_p->fn_dp);
}
}
return true;
}

View File

@ -71,10 +71,10 @@ static lv_labels_t lv_labels_txt = {
* @param copy_dp pointer to a button object, if not NULL then the new object will be copied from it
* @return pointer to the created button
*/
lv_obj_t* lv_label_create(lv_obj_t* par_dp, lv_obj_t * ori_dp)
lv_obj_t* lv_label_create(lv_obj_t* par_dp, lv_obj_t * copy_dp)
{
/*Create a basic object*/
lv_obj_t* new_obj = lv_obj_create(par_dp, ori_dp);
lv_obj_t* new_obj = lv_obj_create(par_dp, copy_dp);
dm_assert(new_obj);
/*Extend the basic object to a label object*/
@ -87,7 +87,7 @@ lv_obj_t* lv_label_create(lv_obj_t* par_dp, lv_obj_t * ori_dp)
lv_obj_set_signal_f(new_obj, lv_label_signal);
/*Init the new label*/
if(ori_dp == NULL) {
if(copy_dp == NULL) {
lv_obj_set_opa(new_obj, OPA_COVER);
lv_obj_set_click(new_obj, false);
lv_obj_set_style(new_obj, &lv_labels_def);
@ -96,8 +96,8 @@ lv_obj_t* lv_label_create(lv_obj_t* par_dp, lv_obj_t * ori_dp)
}
/*Copy 'ori_dp' if not NULL*/
else {
lv_label_set_fixw(new_obj, lv_label_get_fixw(ori_dp));
lv_label_set_text(new_obj, lv_label_get_text(ori_dp));
lv_label_set_fixw(new_obj, lv_label_get_fixw(copy_dp));
lv_label_set_text(new_obj, lv_label_get_text(copy_dp));
}
return new_obj;
}
@ -127,8 +127,9 @@ bool lv_label_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param)
label_p->txt_dp = NULL;
break;
case LV_SIGNAL_STYLE_CHG:
lv_label_set_text(obj_dp, lv_label_get_text(obj_dp));
lv_label_set_text(obj_dp, NULL);
break;
default:
break;
}
@ -144,23 +145,30 @@ bool lv_label_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param)
/**
* Set a new text for a label
* @param obj_dp pointer to a label object
* @param text '\0' terminated character string
* @param text '\0' terminated character string. If NULL then refresh with the current text.
*/
void lv_label_set_text(lv_obj_t * obj_dp, const char * text)
{
if(text == NULL) return;
lv_obj_inv(obj_dp);
lv_label_ext_t * ext_p = lv_obj_get_ext(obj_dp);
uint32_t len = strlen(text) + 1;
lv_label_ext_t * label_ext_dp = lv_obj_get_ext(obj_dp);
if(ext_p->txt_dp != NULL && text != ext_p->txt_dp) {
dm_free(ext_p->txt_dp);
if(text == label_ext_dp->txt_dp) text = NULL;
if(text != NULL) {
uint32_t len = strlen(text) + 1;
if(label_ext_dp->txt_dp != NULL) {
dm_free(label_ext_dp->txt_dp);
}
label_ext_dp->txt_dp = dm_alloc(len);
strcpy(label_ext_dp->txt_dp, text);
} else {
text = label_ext_dp->txt_dp;
}
ext_p->txt_dp = dm_alloc(len);
strcpy(ext_p->txt_dp, text);
/*If 'text" still NULL then nothing to do: return*/
if(text == NULL) return;
uint32_t line_start = 0;
uint32_t new_line_start = 0;
@ -173,7 +181,7 @@ void lv_label_set_text(lv_obj_t * obj_dp, const char * text)
cord_t act_line_length;
/*If the fix width is not enabled the set the max length to very big */
if(ext_p->fixw == 0) {
if(label_ext_dp->fixw == 0) {
max_length = LV_CORD_MAX;
}
@ -185,7 +193,7 @@ void lv_label_set_text(lv_obj_t * obj_dp, const char * text)
new_height += labels_p->line_space;
/*If no fix width then calc. the longest line */
if(ext_p->fixw == false) {
if(label_ext_dp->fixw == false) {
act_line_length = txt_get_width(&text[line_start], new_line_start - line_start,
font_p, labels_p->letter_space);
if(act_line_length > longest_line) {
@ -199,7 +207,7 @@ void lv_label_set_text(lv_obj_t * obj_dp, const char * text)
/*Correction with the last line space*/
new_height -= labels_p->line_space;
if(ext_p->fixw == 0) {
if(label_ext_dp->fixw == 0) {
/*Refresh the full size */
lv_obj_set_size(obj_dp, longest_line, new_height);
} else {
@ -253,7 +261,7 @@ bool lv_label_get_fixw(lv_obj_t * obj_dp)
* Get the relative x and y coordinates of a letter
* @param obj_dp pointer to a label object
* @param index index of the letter (0 ... text length)
* @param pos_p store the result here
* @param pos_p store the result here (E.g. index = 0 gives 0;0 coordinates)
*/
void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p)
{
@ -273,9 +281,9 @@ void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p)
}
/*Search the line of the index letter */;
while (text[line_start] != '\0') {
while (text[new_line_start] != '\0') {
new_line_start += txt_get_next_line(&text[line_start], font_p, labels_p->letter_space, max_length);
if(index < new_line_start) break; /*Lines of index letter begins at 'line_start'*/
if(index < new_line_start || text[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/
y += letter_height + labels_p->line_space;
line_start = new_line_start;
@ -300,6 +308,12 @@ void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p)
}
/**
* Get the index of letter on a relative point of a label
* @param obj_dp pointer to label object
* @param pos_p pointer to point with coordinates on a the label
* @return the index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter)
*/
uint16_t lv_label_get_letter_on(lv_obj_t * obj_dp, point_t * pos_p)
{
const char * text = lv_label_get_text(obj_dp);
@ -337,7 +351,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * obj_dp, point_t * pos_p)
uint32_t i;
for(i = line_start; i < new_line_start-1; i++) {
x += font_get_width(font_p, text[i]) + labels_p->letter_space;
if(pos_p->x <= x) break;
if(pos_p->x < x) break;
}
@ -392,23 +406,23 @@ lv_labels_t * lv_labels_get(lv_labels_builtin_t style, lv_labels_t * copy_p)
* @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_label_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
{
/* A label never covers an area */
if(mode == LV_DESIGN_COVER_CHK) return false;
/*TEST: draw a background for the label*/
/*lv_vfill(&obj_dp->cords, mask_p, COLOR_LIME, OPA_COVER); */
area_t cords;
lv_obj_get_cords(obj_dp, &cords);
opa_t opa= lv_obj_get_opa(obj_dp);
const char * txt = lv_label_get_text(obj_dp);
lv_draw_label(&cords, mask_p, lv_obj_get_style(obj_dp), opa, txt);
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*TEST: draw a background for the label*/
/*lv_vfill(&obj_dp->cords, mask_p, COLOR_LIME, OPA_COVER); */
area_t cords;
lv_obj_get_cords(obj_dp, &cords);
opa_t opa= lv_obj_get_opa(obj_dp);
const char * txt = lv_label_get_text(obj_dp);
lv_draw_label(&cords, mask_p, lv_obj_get_style(obj_dp), opa, txt);
}
return true;
}

View File

@ -235,6 +235,7 @@ uint8_t lv_led_get_bright(lv_obj_t * obj_dp)
* @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_led_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -242,26 +243,23 @@ static bool lv_led_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mod
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return false;
} else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Make darker colors in a temporary style according to the brightness*/
lv_led_ext_t * led_ext_p = lv_obj_get_ext(obj_dp);
lv_leds_t * leds_p = lv_obj_get_style(obj_dp);
lv_leds_t leds_tmp;
memcpy(&leds_tmp, leds_p, sizeof(leds_tmp));
leds_tmp.rects.objs.color = color_mix(leds_tmp.rects.objs.color, COLOR_BLACK, led_ext_p->bright);
leds_tmp.rects.gcolor = color_mix(leds_tmp.rects.gcolor, COLOR_BLACK, led_ext_p->bright);
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
lv_draw_rect(&area, mask_p, &leds_tmp.rects, opa);
}
/*Draw the object*/
/*Make darker colors in a temporary style according to the brightness*/
lv_led_ext_t * led_ext_p = lv_obj_get_ext(obj_dp);
lv_leds_t * leds_p = lv_obj_get_style(obj_dp);
lv_leds_t leds_tmp;
memcpy(&leds_tmp, leds_p, sizeof(leds_tmp));
leds_tmp.rects.objs.color = color_mix(leds_tmp.rects.objs.color, COLOR_BLACK, led_ext_p->bright);
leds_tmp.rects.gcolor = color_mix(leds_tmp.rects.gcolor, COLOR_BLACK, led_ext_p->bright);
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
lv_draw_rect(&area, mask_p, &leds_tmp.rects, opa);
return true;
}

View File

@ -13,7 +13,7 @@
#include "../lv_draw/lv_draw_vbasic.h"
#include "../lv_draw/lv_draw_rbasic.h"
#include "../lv_draw/lv_draw.h"
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include <misc/math/math_base.h>
#include <misc/mem/dyn_mem.h>
#include <misc/others/color.h>
@ -283,49 +283,50 @@ lv_lines_t * lv_lines_get(lv_lines_builtin_t style, lv_lines_t * copy_p)
* @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_line_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
{
/*A line never covers an area*/
if(mode == LV_DESIGN_COVER_CHK) return false;
lv_line_ext_t * ext_p = lv_obj_get_ext(obj_dp);
else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_line_ext_t * ext_p = lv_obj_get_ext(obj_dp);
if(ext_p->point_num == 0 || ext_p->point_p == NULL) return false;
if(ext_p->point_num == 0 || ext_p->point_p == NULL) return false;
lv_lines_t * lines_p = lv_obj_get_style(obj_dp);
lv_lines_t * lines_p = lv_obj_get_style(obj_dp);
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
cord_t x_ofs = area.x1;
cord_t y_ofs = area.y1;
point_t p1;
point_t p2;
cord_t h = lv_obj_get_height(obj_dp);
uint16_t i;
uint8_t us = 1;
if(ext_p->upscale != 0) {
us = LV_DOWNSCALE;
}
/*Read all pints and draw the lines*/
for (i = 0; i < ext_p->point_num - 1; i++) {
p1.x = ext_p->point_p[i].x * us + x_ofs;
p2.x = ext_p->point_p[i + 1].x * us + x_ofs;
if(ext_p->y_inv == 0) {
p1.y = ext_p->point_p[i].y * us + y_ofs;
p2.y = ext_p->point_p[i + 1].y * us + y_ofs;
} else {
p1.y = h - ext_p->point_p[i].y * us + y_ofs;
p2.y = h - ext_p->point_p[i + 1].y * us + y_ofs;
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
cord_t x_ofs = area.x1;
cord_t y_ofs = area.y1;
point_t p1;
point_t p2;
cord_t h = lv_obj_get_height(obj_dp);
uint16_t i;
uint8_t us = 1;
if(ext_p->upscale != 0) {
us = LV_DOWNSCALE;
}
lv_draw_line(&p1, &p2, mask_p, lines_p, opa);
}
/*Read all pints and draw the lines*/
for (i = 0; i < ext_p->point_num - 1; i++) {
p1.x = ext_p->point_p[i].x * us + x_ofs;
p2.x = ext_p->point_p[i + 1].x * us + x_ofs;
if(ext_p->y_inv == 0) {
p1.y = ext_p->point_p[i].y * us + y_ofs;
p2.y = ext_p->point_p[i + 1].y * us + y_ofs;
} else {
p1.y = h - ext_p->point_p[i].y * us + y_ofs;
p2.y = h - ext_p->point_p[i + 1].y * us + y_ofs;
}
lv_draw_line(&p1, &p2, mask_p, lines_p, opa);
}
}
return true;
}

View File

@ -35,13 +35,72 @@ static bool lv_list_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mo
static lv_lists_t lv_lists_def =
{
/*Page style*/
.pages.bg_rects.objs.color = COLOR_MAKE(0x20, 0x50, 0x80), .pages.bg_rects.gcolor = COLOR_SILVER, .pages.bg_rects.bcolor = COLOR_GRAY,
.pages.bg_rects.bopa = 50, .pages.bg_rects.bwidth = 0 * LV_STYLE_MULT, .pages.bg_rects.round = 2 * LV_STYLE_MULT,
.pages.bg_rects.empty = 1,
.pages.bg_rects.objs.color = COLOR_MAKE(0x50, 0x70, 0x90), .pages.bg_rects.gcolor = COLOR_MAKE(0x70, 0xA0, 0xC0),
.pages.bg_rects.bcolor = COLOR_WHITE, .pages.bg_rects.bopa = 50, .pages.bg_rects.bwidth = 2 * LV_STYLE_MULT,
.pages.bg_rects.round = 4 * LV_STYLE_MULT,
.pages.bg_rects.empty = 0,
.pages.bg_rects.vpad = 10 * LV_STYLE_MULT,
.pages.bg_rects.hpad = 10 * LV_STYLE_MULT,
.pages.bg_rects.opad = 5 * LV_STYLE_MULT,
.pages.scrable_rects.objs.color = COLOR_WHITE,
.pages.scrable_rects.gcolor = COLOR_SILVER,
.pages.scrable_rects.bcolor = COLOR_GRAY,
.pages.scrable_rects.bopa = 100,
.pages.scrable_rects.bwidth = 2 * LV_STYLE_MULT,
.pages.scrable_rects.round = 4 * LV_STYLE_MULT,
.pages.scrable_rects.empty = 0,
.pages.scrable_rects.hpad = 10 * LV_STYLE_MULT,
.pages.scrable_rects.vpad = 10 * LV_STYLE_MULT,
.pages.scrable_rects.opad = 10 * LV_STYLE_MULT,
.pages.sb_rects.objs.color = COLOR_BLACK, .pages.sb_rects.gcolor = COLOR_BLACK, .pages.sb_rects.bcolor = COLOR_WHITE,
.pages.sb_rects.bopa = 50, .pages.sb_rects.bwidth = 1 * LV_STYLE_MULT, .pages.sb_rects.round = 5 * LV_STYLE_MULT,
.pages.sb_rects.empty = 0, .pages.sb_width= 8 * LV_STYLE_MULT, .pages.sb_opa=50, .pages.sb_mode = LV_PAGE_SB_MODE_AUTO,
/*List element style*/
.liste_btns.mcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0xa0, 0xa0, 0xa0), .liste_btns.gcolor[LV_BTN_STATE_REL] = COLOR_WHITE, .liste_btns.bcolor[LV_BTN_STATE_REL] = COLOR_WHITE,
.liste_btns.mcolor[LV_BTN_STATE_PR] = COLOR_MAKE(0xa0, 0xa0, 0xa0), .liste_btns.gcolor[LV_BTN_STATE_PR] = COLOR_MAKE(0xa0, 0xc0, 0xe0), .liste_btns.bcolor[LV_BTN_STATE_PR] = COLOR_WHITE,
.liste_btns.mcolor[LV_BTN_STATE_TGL_REL] = COLOR_MAKE(0x60,0x80,0xa0), .liste_btns.gcolor[LV_BTN_STATE_TGL_REL] = COLOR_MAKE(0xc0, 0xd0, 0xf0), .liste_btns.bcolor[LV_BTN_STATE_TGL_REL] = COLOR_WHITE,
.liste_btns.mcolor[LV_BTN_STATE_TGL_PR] = COLOR_MAKE(0x60, 0x80, 0xa0), .liste_btns.gcolor[LV_BTN_STATE_TGL_PR] = COLOR_MAKE(0x80, 0xa0, 0xc0), .liste_btns.bcolor[LV_BTN_STATE_TGL_PR] = COLOR_WHITE,
.liste_btns.mcolor[LV_BTN_STATE_INA] = COLOR_SILVER, .liste_btns.gcolor[LV_BTN_STATE_INA] = COLOR_GRAY, .liste_btns.bcolor[LV_BTN_STATE_INA] = COLOR_WHITE,
.liste_btns.rects.bwidth = 2 * LV_STYLE_MULT, .liste_btns.rects.bopa = 50,
.liste_btns.rects.empty = 0, .liste_btns.rects.round = 4 * LV_STYLE_MULT,
.liste_btns.rects.hpad = 10 * LV_STYLE_MULT,
.liste_btns.rects.vpad = 10 * LV_STYLE_MULT,
.liste_btns.rects.opad = 20 * LV_STYLE_MULT,
.liste_labels.objs.color = COLOR_MAKE(0x20,0x20,0x20), .liste_labels.font = LV_FONT_DEFAULT,
.liste_labels.letter_space = 2 * LV_STYLE_MULT, .liste_labels.line_space = 2 * LV_STYLE_MULT,
.liste_labels.mid = 0,
.liste_imgs.recolor_opa = OPA_COVER,
.liste_layout = LV_RECT_LAYOUT_ROW_M
};
static lv_lists_t lv_lists_tight =
{
/*Page style*/
.pages.bg_rects.objs.color = COLOR_MAKE(0x50, 0x70, 0x90), .pages.bg_rects.gcolor = COLOR_MAKE(0x70, 0xA0, 0xC0),
.pages.bg_rects.bcolor = COLOR_WHITE, .pages.bg_rects.bopa = 50, .pages.bg_rects.bwidth = 0 * LV_STYLE_MULT,
.pages.bg_rects.round = 4 * LV_STYLE_MULT,
.pages.bg_rects.empty = 1,
.pages.bg_rects.vpad = 0 * LV_STYLE_MULT,
.pages.bg_rects.hpad = 0 * LV_STYLE_MULT,
.pages.bg_rects.opad = 0 * LV_STYLE_MULT,
.pages.scrable_rects.objs.color = COLOR_WHITE,
.pages.scrable_rects.gcolor = COLOR_SILVER,
.pages.scrable_rects.bcolor = COLOR_GRAY,
.pages.scrable_rects.bopa = 100,
.pages.scrable_rects.bwidth = 0 * LV_STYLE_MULT,
.pages.scrable_rects.round = 0 * LV_STYLE_MULT,
.pages.scrable_rects.empty = 0,
.pages.scrable_rects.hpad = 0 * LV_STYLE_MULT,
.pages.scrable_rects.vpad = 0 * LV_STYLE_MULT,
.pages.scrable_rects.opad = 0 * LV_STYLE_MULT,
.pages.sb_rects.objs.color = COLOR_BLACK, .pages.sb_rects.gcolor = COLOR_BLACK, .pages.sb_rects.bcolor = COLOR_WHITE,
.pages.sb_rects.bopa = 50, .pages.sb_rects.bwidth = 1 * LV_STYLE_MULT, .pages.sb_rects.round = 5 * LV_STYLE_MULT,
.pages.sb_rects.empty = 0, .pages.sb_width= 8 * LV_STYLE_MULT, .pages.sb_opa=50, .pages.sb_mode = LV_PAGE_SB_MODE_AUTO,
@ -91,13 +150,18 @@ lv_obj_t* lv_list_create(lv_obj_t* par_dp, lv_obj_t * copy_dp)
lv_obj_t * new_obj_dp = lv_page_create(par_dp, copy_dp);
dm_assert(new_obj_dp);
lv_list_ext_t * ext_p= lv_obj_alloc_ext(new_obj_dp, sizeof(lv_list_ext_t));
lv_obj_set_signal_f(new_obj_dp, lv_list_signal);
/*Init the new list object*/
if(copy_dp == NULL) {
ext_p->fit = LV_LIST_FIT_LONGEST;
lv_obj_set_signal_f(new_obj_dp, lv_list_signal);
lv_obj_set_size_us(new_obj_dp, 100, 150);
lv_obj_set_style(new_obj_dp, &lv_lists_def);
lv_rect_set_layout(new_obj_dp, LV_LIST_LAYOUT_DEF);
lv_rect_set_layout(LV_EA(new_obj_dp, lv_list_ext_t)->page_ext.scrolling_dp, LV_LIST_LAYOUT_DEF);
} else {
lv_list_ext_t * copy_ext_dp = lv_obj_get_ext(copy_dp);
ext_p->fit = copy_ext_dp->fit;
}
return new_obj_dp;
@ -147,7 +211,7 @@ lv_obj_t * lv_list_add(lv_obj_t * obj_dp, const char * img_fn, const char * txt,
lv_obj_set_style(liste, &lists_p->liste_btns);
lv_btn_set_rel_action(liste, rel_action);
lv_page_glue_obj(liste, true);
lv_rect_set_layout(liste, lv_lists_def.liste_layout);
lv_rect_set_layout(liste, lists_p->liste_layout);
lv_rect_set_fit(liste, true, true); /*hor. fit might be disabled later*/
if(img_fn != NULL) {
@ -168,7 +232,7 @@ lv_obj_t * lv_list_add(lv_obj_t * obj_dp, const char * img_fn, const char * txt,
if(ext_p->fit == LV_LIST_FIT_HOLDER) {
/*Now the width will be adjusted*/
lv_rect_set_fit(liste, false, true);
cord_t w = lv_obj_get_width(lv_obj_get_parent(obj_dp));
cord_t w = lv_obj_get_width(obj_dp);
w -= lists_p->pages.bg_rects.hpad * 2;
lv_obj_set_width(liste, w);
} else if(ext_p->fit == LV_LIST_FIT_LONGEST) {
@ -178,51 +242,26 @@ lv_obj_t * lv_list_add(lv_obj_t * obj_dp, const char * img_fn, const char * txt,
lv_obj_t * e;
cord_t w = 0;
/*Get the longest list element*/
e = lv_obj_get_child(obj_dp, NULL);
lv_obj_t * e_par = lv_obj_get_parent(liste); /*The page changes the parent so get it*/
e = lv_obj_get_child(e_par, NULL);
while(e != NULL) {
w = max(w, lv_obj_get_width(e));
e = lv_obj_get_child(obj_dp, e);
e = lv_obj_get_child(e_par, e);
}
/*Set all list element to the longest width*/
e = lv_obj_get_child(obj_dp, NULL);
e = lv_obj_get_child(e_par, NULL);
while(e != NULL) {
if(lv_obj_get_width(e) != w) {
lv_obj_set_width(e, w);
}
e = lv_obj_get_child(obj_dp, e);
e = lv_obj_get_child(e_par, e);
}
}
return liste;
}
/**
* Return with a pointer to a built-in style and/or copy it to a variable
* @param style a style name from lv_lists_builtin_t enum
* @param copy_p copy the style to this variable. (NULL if unused)
* @return pointer to an lv_lists_t style
*/
lv_lists_t * lv_lists_get(lv_lists_builtin_t style, lv_lists_t * copy_p)
{
lv_lists_t *style_p;
switch(style) {
case LV_LISTS_DEF:
style_p = &lv_lists_def;
break;
default:
style_p = &lv_lists_def;
}
if(copy_p != NULL) {
if(style_p != NULL) memcpy(copy_p, style_p, sizeof(lv_lists_t));
else memcpy(copy_p, &lv_lists_def, sizeof(lv_lists_t));
}
return style_p;
}
/**
* Move the list elements up by one
* @param obj_dp pointer a to list object
@ -298,6 +337,38 @@ lv_list_fit_t lv_list_get_fit(lv_obj_t * obj_dp)
return LV_EA(obj_dp, lv_list_ext_t)->fit;
}
/**
* Return with a pointer to a built-in style and/or copy it to a variable
* @param style a style name from lv_lists_builtin_t enum
* @param copy_p copy the style to this variable. (NULL if unused)
* @return pointer to an lv_lists_t style
*/
lv_lists_t * lv_lists_get(lv_lists_builtin_t style, lv_lists_t * copy_p)
{
lv_lists_t *style_p;
switch(style) {
case LV_LISTS_DEF:
case LV_LISTS_GAP:
style_p = &lv_lists_def;
break;
case LV_LISTS_TIGHT:
style_p = &lv_lists_tight;
break;
default:
style_p = &lv_lists_def;
}
if(copy_p != NULL) {
if(style_p != NULL) memcpy(copy_p, style_p, sizeof(lv_lists_t));
else memcpy(copy_p, &lv_lists_def, sizeof(lv_lists_t));
}
return style_p;
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -310,6 +381,7 @@ lv_list_fit_t lv_list_get_fit(lv_obj_t * obj_dp)
* @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_list_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)

View File

@ -40,6 +40,8 @@ typedef struct
typedef enum
{
LV_LISTS_DEF,
LV_LISTS_GAP,
LV_LISTS_TIGHT,
}lv_lists_builtin_t;
typedef enum

View File

@ -156,6 +156,7 @@ lv_templs_t * lv_templs_get(lv_templs_builtin_t style, lv_templs_t * copy_p)
* @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_templ_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)

View File

@ -12,7 +12,8 @@
#include "misc/math/math_base.h"
#include "../lv_objx/lv_page.h"
#include "../lv_objx/lv_rect.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_obj/lv_refr.h"
/*********************
* DEFINES
@ -26,23 +27,38 @@
* STATIC PROTOTYPES
**********************/
static void lv_page_sb_refresh(lv_obj_t* main_dp);
static bool lv_page_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode);
static bool lv_scrolling_signal(lv_obj_t* obj_dp, lv_signal_t sign, void* param);
/**********************
* STATIC VARIABLES
**********************/
static lv_design_f_t ancestor_design_f;
static lv_pages_t lv_pages_def =
{
.bg_rects.objs.color = COLOR_WHITE,
.bg_rects.gcolor = COLOR_SILVER,
.bg_rects.bcolor = COLOR_GRAY,
.bg_rects.objs.color = COLOR_MAKE(0x50, 0x70, 0x90),
.bg_rects.gcolor = COLOR_MAKE(0x70, 0xA0, 0xC0),
.bg_rects.bcolor = COLOR_WHITE,
.bg_rects.bopa = 50,
.bg_rects.bwidth = 0 * LV_STYLE_MULT,
.bg_rects.round = 2 * LV_STYLE_MULT,
.bg_rects.bwidth = 2 * LV_STYLE_MULT,
.bg_rects.round = 4 * LV_STYLE_MULT,
.bg_rects.empty = 0,
.bg_rects.hpad = 10 * LV_STYLE_MULT,
.bg_rects.vpad = 10 * LV_STYLE_MULT,
.bg_rects.opad = 5 * LV_STYLE_MULT,
.scrable_rects.objs.color = COLOR_WHITE,
.scrable_rects.gcolor = COLOR_SILVER,
.scrable_rects.bcolor = COLOR_GRAY,
.scrable_rects.bopa = 50,
.scrable_rects.bwidth = 0 * LV_STYLE_MULT,
.scrable_rects.round = 2 * LV_STYLE_MULT,
.scrable_rects.empty = 0,
.scrable_rects.hpad = 10 * LV_STYLE_MULT,
.scrable_rects.vpad = 10 * LV_STYLE_MULT,
.scrable_rects.opad = 5 * LV_STYLE_MULT,
.sb_rects.objs.color = COLOR_BLACK,
.sb_rects.gcolor = COLOR_BLACK,
.sb_rects.bcolor = COLOR_WHITE,
@ -56,47 +72,29 @@ static lv_pages_t lv_pages_def =
.sb_width= 8 * LV_STYLE_MULT,
.sb_opa=50,
.sb_mode = LV_PAGE_SB_MODE_ON,
.sb_mode = LV_PAGE_SB_MODE_AUTO,
};
static lv_pages_t lv_pages_paper =
{
.bg_rects.objs.color = COLOR_WHITE,
.bg_rects.gcolor = COLOR_WHITE,
.bg_rects.bcolor = COLOR_GRAY,
.bg_rects.bopa = 100,
.bg_rects.bwidth = 2 * LV_STYLE_MULT,
.bg_rects.round = 0 * LV_STYLE_MULT,
.bg_rects.empty = 0,
.bg_rects.hpad = 20 * LV_STYLE_MULT,
.bg_rects.vpad = 20 * LV_STYLE_MULT,
.bg_rects.opad = 10 * LV_STYLE_MULT,
.sb_rects.objs.color = COLOR_BLACK,
.sb_rects.gcolor = COLOR_BLACK,
.sb_rects.bcolor = COLOR_SILVER,
.sb_rects.bopa = 100,
.sb_rects.bwidth = 1 * LV_STYLE_MULT,
.sb_rects.round = 5 * LV_STYLE_MULT,
.sb_rects.empty = 0,
.sb_rects.hpad = 0,
.sb_rects.vpad = 0,
.sb_rects.opad = 0,
.sb_width = 10 * LV_STYLE_MULT,
.sb_opa=50,
.sb_mode = LV_PAGE_SB_MODE_ON,
};
static lv_pages_t lv_pages_transp =
{
.bg_rects.objs.transp = 1,
.bg_rects.empty = 1,
.bg_rects.bwidth = 0,
.bg_rects.objs.color = COLOR_MAKE(0x50, 0x70, 0x90),
.bg_rects.gcolor = COLOR_MAKE(0x70, 0xA0, 0xC0),
.bg_rects.bcolor = COLOR_WHITE,
.bg_rects.bopa = 50,
.bg_rects.bwidth = 0 * LV_STYLE_MULT,
.bg_rects.round = 2 * LV_STYLE_MULT,
.bg_rects.empty = 0,
.bg_rects.hpad = 10 * LV_STYLE_MULT,
.bg_rects.vpad = 10 * LV_STYLE_MULT,
.bg_rects.vpad = 10 * LV_STYLE_MULT,
.bg_rects.opad = 5 * LV_STYLE_MULT,
.scrable_rects.objs.transp = 1,
.scrable_rects.empty = 1,
.scrable_rects.bwidth = 0,
.scrable_rects.hpad = 10 * LV_STYLE_MULT,
.scrable_rects.vpad = 10 * LV_STYLE_MULT,
.scrable_rects.vpad = 10 * LV_STYLE_MULT,
.sb_rects.objs.color = COLOR_BLACK,
.sb_rects.gcolor = COLOR_BLACK,
@ -129,57 +127,52 @@ static lv_pages_t lv_pages_transp =
/**
* Create a page objects
* @param par_dp pointer to an object, it will be the parent of the new page
* @param copy_dp pointer to a page object, if not NULL then the new object will be copied from it
* @return pointer to the created page
*/
lv_obj_t* lv_page_create(lv_obj_t * par_dp, lv_obj_t * ori_dp)
lv_obj_t* lv_page_create(lv_obj_t * par_dp, lv_obj_t * copy_dp)
{
lv_obj_t* new_dp = NULL;
/*Create a basic object. Page elements will be stored here*/
new_dp = lv_rect_create(par_dp, ori_dp);
/*Init the new object*/
lv_page_ext_t * page_p = lv_obj_alloc_ext(new_dp, sizeof(lv_page_ext_t));
/*Create the ancestor object*/
lv_obj_t * new_obj_dp = lv_rect_create(par_dp, copy_dp);
dm_assert(new_obj_dp);
/*Init the main rectangle if it is not copied*/
if(ori_dp == NULL) {
lv_obj_set_drag(new_dp, true);
lv_obj_set_drag_throw(new_dp, true);
lv_obj_set_style(new_dp, &lv_pages_def);
lv_rect_set_fit(new_dp, true, true);
} else {
lv_obj_set_style(new_dp, lv_obj_get_style(ori_dp));
/*Allocate the object type specific extended data*/
lv_page_ext_t * ext_dp = lv_obj_alloc_ext(new_obj_dp, sizeof(lv_page_ext_t));
dm_assert(ext_dp);
if(ancestor_design_f == NULL) {
ancestor_design_f = lv_obj_get_design_f(new_obj_dp);
}
lv_pages_t * pages_p = lv_obj_get_style(new_dp);
/*Create horizontal scroll bar*/
page_p->sbh_dp = lv_rect_create(par_dp, NULL);
lv_obj_set_height(page_p->sbh_dp, pages_p->sb_width);
lv_obj_set_style(page_p->sbh_dp, &pages_p->sb_rects);
lv_obj_set_click(page_p->sbh_dp, false);
if(pages_p->sb_mode == LV_PAGE_SB_MODE_ON) {
lv_obj_set_opa(page_p->sbh_dp, (pages_p->sb_opa * OPA_COVER) / 100);
/*Init the new page object*/
if(copy_dp == NULL) {
ext_dp->scrolling_dp = lv_rect_create(new_obj_dp, NULL);
lv_obj_set_signal_f(ext_dp->scrolling_dp, lv_scrolling_signal);
lv_obj_set_drag(ext_dp->scrolling_dp, true);
lv_obj_set_drag_throw(ext_dp->scrolling_dp, true);
lv_rect_set_fit(ext_dp->scrolling_dp, true, true);
lv_obj_set_style(ext_dp->scrolling_dp, &lv_pages_def.scrable_rects);
/* Add the signal function only if 'scrolling_dp' is created
* because everything has to be ready before any signal is received*/
lv_obj_set_signal_f(new_obj_dp, lv_page_signal);
lv_obj_set_design_f(new_obj_dp, lv_page_design);
lv_obj_set_style(new_obj_dp, &lv_pages_def);
} else {
lv_obj_set_opa(page_p->sbh_dp, OPA_TRANSP);
}
lv_page_ext_t * copy_ext_dp = lv_obj_get_ext(copy_dp);
ext_dp->scrolling_dp = lv_rect_create(new_obj_dp, copy_ext_dp->scrolling_dp);
lv_obj_set_signal_f(ext_dp->scrolling_dp, lv_scrolling_signal);
/*Create vertical scroll bar*/
page_p->sbv_dp =lv_rect_create(par_dp, NULL);
lv_obj_set_width(page_p->sbv_dp, pages_p->sb_width);
lv_obj_set_style(page_p->sbv_dp, &pages_p->sb_rects);
lv_obj_set_click(page_p->sbv_dp, false);
if(lv_pages_def.sb_mode == LV_PAGE_SB_MODE_ON) {
lv_obj_set_opa(page_p->sbv_dp, (pages_p->sb_opa * OPA_COVER) / 100);
} else {
lv_obj_set_opa(page_p->sbv_dp, OPA_TRANSP);
/* Add the signal function only if 'scrolling_dp' is created
* because everything has to be ready before any signal is received*/
lv_obj_set_signal_f(new_obj_dp, lv_page_signal);
lv_obj_set_design_f(new_obj_dp, lv_page_design);
lv_obj_set_style(new_obj_dp, lv_obj_get_style(copy_dp));
}
lv_obj_set_signal_f(new_dp, lv_page_signal);
lv_page_sb_refresh(new_dp);
lv_page_sb_refresh(new_obj_dp);
return new_dp;
return new_obj_dp;
}
@ -199,99 +192,42 @@ bool lv_page_signal(lv_obj_t* obj_dp, lv_signal_t sign, void* param)
/* The object can be deleted so check its validity and then
* 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 par_cords;
lv_obj_t * par_dp = lv_obj_get_parent(obj_dp);
lv_page_ext_t * page_ext_p = lv_obj_get_ext(obj_dp);
lv_pages_t * pages_p = lv_obj_get_style(obj_dp);
lv_obj_t * child;
switch(sign) {
case LV_SIGNAL_CORD_CHG:
new_x = lv_obj_get_x(obj_dp);
new_y = lv_obj_get_y(obj_dp);
lv_obj_get_cords(par_dp, &par_cords);
lv_obj_get_cords(obj_dp, &page_cords);
/*page width smaller then parent width? -> align to left*/
if(area_get_width(&page_cords) <= area_get_width(&par_cords)) {
if(page_cords.x1 != par_cords.x1) {
new_x = 0;
refr_x = true;
}
} else {
if(page_cords.x2 < par_cords.x2) {
new_x = area_get_width(&par_cords) - area_get_width(&page_cords); /* Right align */
refr_x = true;
}
if (page_cords.x1 > par_cords.x1) {
new_x = 0; /*Left align*/
refr_x = true;
}
}
/*Wrong in y?*/
if(area_get_height(&page_cords) <= area_get_height(&par_cords)) {
if(page_cords.y1 != par_cords.y1) {
new_y = 0;
refr_y = true;
}
} else {
if(page_cords.y2 < par_cords.y2) {
new_y = area_get_height(&par_cords) - area_get_height(&page_cords); /* Bottom align */
refr_y = true;
}
if (page_cords.y1 > par_cords.y1) {
new_y = 0; /*Top align*/
refr_y = true;
}
}
if(refr_x != false || refr_y != false) {
lv_obj_set_pos(obj_dp, new_x, new_y);
}
lv_page_sb_refresh(obj_dp);
break;
case LV_SIGNAL_DRAG_BEGIN:
if(pages_p->sb_mode == LV_PAGE_SB_MODE_AUTO ) {
if(lv_obj_get_height(page_ext_p->sbv_dp) < lv_obj_get_height(par_dp) - pages_p->sb_width) {
lv_obj_set_opa(page_ext_p->sbv_dp, (pages_p->sb_opa * OPA_COVER) / 100);
}
if(lv_obj_get_width(page_ext_p->sbh_dp) < lv_obj_get_width(par_dp) - pages_p->sb_width) {
lv_obj_set_opa(page_ext_p->sbh_dp, (pages_p->sb_opa * OPA_COVER) / 100);
}
}
break;
case LV_SIGNAL_DRAG_END:
if(pages_p->sb_mode == LV_PAGE_SB_MODE_AUTO) {
lv_obj_set_opa(page_ext_p->sbh_dp, OPA_TRANSP);
lv_obj_set_opa(page_ext_p->sbv_dp, OPA_TRANSP);
}
break;
case LV_SIGNAL_CHILD_CHG: /*Be sure, only scrollable object is on the page*/
child = lv_obj_get_child(obj_dp, NULL);
while(child != NULL) {
if(child != page_ext_p->scrolling_dp) {
lv_obj_t * tmp = child;
child = lv_obj_get_child(obj_dp, child); /*Get the next child before move this*/
lv_obj_set_parent(tmp, page_ext_p->scrolling_dp);
} else {
child = lv_obj_get_child(obj_dp, child);
}
}
break;
case LV_SIGNAL_STYLE_CHG:
lv_obj_set_style(page_ext_p->sbh_dp, &pages_p->sb_rects);
lv_obj_set_style(page_ext_p->sbv_dp, &pages_p->sb_rects);
lv_obj_set_width(page_ext_p->sbv_dp, pages_p->sb_width);
lv_obj_set_height(page_ext_p->sbh_dp, pages_p->sb_width);
area_set_height(&page_ext_p->sbh, pages_p->sb_width);
area_set_width(&page_ext_p->sbv, pages_p->sb_width);
lv_obj_set_style(page_ext_p->scrolling_dp, &pages_p->scrable_rects);
if(pages_p->sb_mode == LV_PAGE_SB_MODE_ON) {
lv_obj_set_opa(page_ext_p->sbv_dp, (pages_p->sb_opa * OPA_COVER) / 100);
lv_obj_set_opa(page_ext_p->sbh_dp, (pages_p->sb_opa * OPA_COVER) / 100);
} else {
lv_obj_set_opa(page_ext_p->sbv_dp, OPA_TRANSP);
lv_obj_set_opa(page_ext_p->sbh_dp, OPA_TRANSP);
}
page_ext_p->sbh_draw = 1;
page_ext_p->sbv_draw = 1;
} else {
page_ext_p->sbh_draw = 0;
page_ext_p->sbv_draw = 0;
}
lv_page_sb_refresh(obj_dp);
break;
case LV_SIGNAL_CORD_CHG:
lv_page_sb_refresh(obj_dp);
break;
default:
break;
@ -301,6 +237,114 @@ bool lv_page_signal(lv_obj_t* obj_dp, lv_signal_t sign, void* param)
return obj_valid;
}
/**
* Signal function of the scrollable part of a page
* @param obj_dp pointer to the scrollable object
* @param sign a signal type from lv_signal_t enum
* @param param pointer to a signal specific variable
*/
static bool lv_scrolling_signal(lv_obj_t* obj_dp, lv_signal_t sign, void* param)
{
bool obj_valid = true;
/* Include the ancient signal function */
obj_valid = lv_rect_signal(obj_dp, sign, param);
/* The object can be deleted so check its validity and then
* 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_p = lv_obj_get_parent(obj_dp);
lv_pages_t * pages_p = lv_obj_get_style(page_p);
lv_page_ext_t * page_ext_dp = lv_obj_get_ext(page_p);
cord_t hpad = pages_p->bg_rects.hpad;
cord_t vpad = pages_p->bg_rects.vpad;
switch(sign) {
case LV_SIGNAL_CORD_CHG:
new_x = lv_obj_get_x(obj_dp);
new_y = lv_obj_get_y(obj_dp);
lv_obj_get_cords(obj_dp, &obj_cords);
lv_obj_get_cords(page_p, &page_cords);
/*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;
}
}
/*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;
}
}
if(refr_x != false || refr_y != false) {
lv_obj_set_pos(obj_dp, new_x, new_y);
}
lv_page_sb_refresh(page_p);
break;
case LV_SIGNAL_DRAG_BEGIN:
if(pages_p->sb_mode == LV_PAGE_SB_MODE_AUTO ) {
if(area_get_height(&page_ext_dp->sbv) < lv_obj_get_height(obj_dp) - pages_p->sb_width) {
page_ext_dp->sbv_draw = 1;
lv_inv_area(&page_ext_dp->sbv);
}
if(area_get_width(&page_ext_dp->sbh) < lv_obj_get_width(obj_dp) - pages_p->sb_width) {
page_ext_dp->sbh_draw = 1;
lv_inv_area(&page_ext_dp->sbh);
}
}
break;
case LV_SIGNAL_DRAG_END:
if(pages_p->sb_mode == LV_PAGE_SB_MODE_AUTO) {
page_ext_dp->sbh_draw = 0;
page_ext_dp->sbv_draw = 0;
lv_inv_area(&page_ext_dp->sbh);
lv_inv_area(&page_ext_dp->sbv);
}
break;
default:
break;
}
}
return obj_valid;
}
/**
* Glue the object to the page. After it the page can be moved (dragged) with this object too.
* @param obj_dp pointer to an object on a page
@ -326,9 +370,6 @@ lv_pages_t * lv_pages_get(lv_pages_builtin_t style, lv_pages_t * to_copy)
case LV_PAGES_DEF:
style_p = &lv_pages_def;
break;
case LV_PAGES_PAPER:
style_p = &lv_pages_paper;
break;
case LV_PAGES_TRANSP:
style_p = &lv_pages_transp;
break;
@ -359,6 +400,40 @@ lv_pages_t * lv_pages_get(lv_pages_builtin_t style, lv_pages_t * to_copy)
* STATIC FUNCTIONS
**********************/
/**
* Handle the drawing related tasks of the pages
* @param obj_dp 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_page_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
return ancestor_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/
lv_page_ext_t * page_ext_dp = lv_obj_get_ext(obj_dp);
lv_pages_t * pages_p = lv_obj_get_style(obj_dp);
opa_t sb_opa = lv_obj_get_opa(obj_dp) * pages_p->sb_opa /100;
/*Draw the scrollbars*/
if(page_ext_dp->sbh_draw != 0) {
lv_draw_rect(&page_ext_dp->sbh, mask_p, &pages_p->sb_rects, sb_opa);
}
if(page_ext_dp->sbv_draw != 0) {
lv_draw_rect(&page_ext_dp->sbv, mask_p, &pages_p->sb_rects, sb_opa);
}
}
return true;
}
/**
* Handle the drawing related tasks of the pages
* @param obj_dp pointer to an object
@ -370,51 +445,59 @@ lv_pages_t * lv_pages_get(lv_pages_builtin_t style, lv_pages_t * to_copy)
*/
static void lv_page_sb_refresh(lv_obj_t* page_dp)
{
lv_page_ext_t * page_p = lv_obj_get_ext(page_dp);
lv_page_ext_t * page_ext_dp = lv_obj_get_ext(page_dp);
lv_pages_t * pages_p = lv_obj_get_style(page_dp);
lv_obj_t* par_dp = lv_obj_get_parent(page_dp);
lv_obj_t* scrolling_dp = page_ext_dp->scrolling_dp;
cord_t size_tmp;
cord_t page_w = lv_obj_get_width(page_dp);
cord_t page_h = lv_obj_get_height(page_dp);
cord_t par_w = lv_obj_get_width(par_dp);
cord_t par_h = lv_obj_get_height(par_dp);
cord_t scrolling_w = lv_obj_get_width(scrolling_dp);
cord_t scrolling_h = lv_obj_get_height(scrolling_dp);
cord_t hpad = pages_p->bg_rects.hpad;
cord_t vpad = pages_p->bg_rects.vpad;
cord_t obj_w = lv_obj_get_width(page_dp);
cord_t obj_h = lv_obj_get_height(page_dp);
cord_t page_x0 = page_dp->cords.x1;
cord_t page_y0 = page_dp->cords.y1;
lv_inv_area(&page_ext_dp->sbh);
lv_inv_area(&page_ext_dp->sbv);
/*Horizontal scrollbar*/
if(page_w <= par_w) { /*Full sized scroll bar*/
lv_obj_set_width(page_p->sbh_dp, par_w - pages_p->sb_width);
lv_obj_set_pos(page_p->sbh_dp, 0, par_h - pages_p->sb_width);
lv_obj_set_opa(page_p->sbh_dp, OPA_TRANSP);
} else {
if(scrolling_w <= obj_w) { /*Full sized scroll bar*/
area_set_width(&page_ext_dp->sbh, obj_w - pages_p->sb_width);
area_set_pos(&page_ext_dp->sbh, page_x0, page_y0 + obj_h - pages_p->sb_width);
} else {
if(pages_p->sb_mode == LV_PAGE_SB_MODE_ON) {
lv_obj_set_opa(page_p->sbh_dp, (pages_p->sb_opa * OPA_COVER) / 100);
page_ext_dp->sbh_draw = 1;
}
size_tmp = (((obj_w - hpad) * (obj_w - pages_p->sb_width)) / scrolling_w);
area_set_width(&page_ext_dp->sbh, size_tmp);
size_tmp = ((par_w * (par_w - pages_p->sb_width)) / page_w);
lv_obj_set_width(page_p->sbh_dp, size_tmp);
lv_obj_set_pos(page_p->sbh_dp,
( -(lv_obj_get_x(page_dp)) * (par_w - size_tmp - pages_p->sb_width)) /
(page_w - par_w),
par_h - pages_p->sb_width);
area_set_pos(&page_ext_dp->sbh, page_x0 +
( -(lv_obj_get_x(scrolling_dp) - hpad) * (obj_w - size_tmp - pages_p->sb_width)) /
(scrolling_w - obj_w + 2 * hpad),
page_y0 + obj_h - pages_p->sb_width);
}
/*Vertical scrollbar*/
if(page_h <= par_h) { /*Full sized scroll bar*/
lv_obj_set_height(page_p->sbv_dp, par_h - pages_p->sb_width);
lv_obj_set_pos(page_p->sbv_dp, par_w - pages_p->sb_width, 0);
lv_obj_set_opa(page_p->sbv_dp, OPA_TRANSP);
if(scrolling_h <= obj_h) { /*Full sized scroll bar*/
area_set_height(&page_ext_dp->sbv, obj_h - pages_p->sb_width);
area_set_pos(&page_ext_dp->sbv, page_x0 + obj_w - pages_p->sb_width, 0);
} else {
if(pages_p->sb_mode == LV_PAGE_SB_MODE_ON) {
lv_obj_set_opa(page_p->sbv_dp, (pages_p->sb_opa * OPA_COVER) / 100);
page_ext_dp->sbv_draw = 1;
}
size_tmp = ((par_h * (par_h - pages_p->sb_width)) / page_h);
lv_obj_set_height(page_p->sbv_dp, size_tmp);
size_tmp = (((obj_h - vpad) * (obj_h - pages_p->sb_width)) / scrolling_h);
area_set_height(&page_ext_dp->sbv, size_tmp);
lv_obj_set_pos(page_p->sbv_dp,
par_w - pages_p->sb_width,
(-(lv_obj_get_y(page_dp)) * (par_h - size_tmp - pages_p->sb_width)) /
(page_h - par_h));
area_set_pos(&page_ext_dp->sbv, page_x0 + obj_w - pages_p->sb_width,
page_y0 +
(-(lv_obj_get_y(scrolling_dp) - vpad) * (obj_h - size_tmp - pages_p->sb_width)) /
(scrolling_h - obj_h + 2 * vpad));
}
lv_inv_area(&page_ext_dp->sbh);
lv_inv_area(&page_ext_dp->sbv);
}
#endif

View File

@ -31,7 +31,9 @@ typedef enum
typedef struct
{
lv_rects_t bg_rects;
lv_rects_t bg_rects; /*Style of ancestor*/
/*New style element for this type */
lv_rects_t scrable_rects;
lv_rects_t sb_rects;
cord_t sb_width;
lv_page_sb_mode_t sb_mode;
@ -41,15 +43,18 @@ typedef struct
typedef struct
{
lv_rect_ext_t rect_ext;
lv_obj_t* sbh_dp; /*Horizontal scrollbar*/
lv_obj_t* sbv_dp; /*Vertical scrollbar*/
lv_rect_ext_t rect_ext; /*Ext. of ancestor*/
/*New data for this type */
lv_obj_t * scrolling_dp; /*The scrollable object on the background*/
area_t sbh; /*Horizontal scrollbar*/
area_t sbv; /*Vertical scrollbar*/
uint8_t sbh_draw :1; /*1: horizontal scrollbar is visible now*/
uint8_t sbv_draw :1; /*1: vertical scrollbar is visible now*/
}lv_page_ext_t;
typedef enum
{
LV_PAGES_DEF,
LV_PAGES_PAPER,
LV_PAGES_TRANSP,
}lv_pages_builtin_t;

View File

@ -252,6 +252,7 @@ lv_pbs_t * lv_pbs_get(lv_pbs_builtin_t style, lv_pbs_t * copy_p)
* @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_pb_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -261,23 +262,20 @@ static bool lv_pb_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return ancestor_design_fp(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design_fp(obj_dp, mask_p, mode);
lv_pb_ext_t * ext_dp = lv_obj_get_ext(obj_dp);
area_t bar_area;
uint32_t tmp;
area_cpy(&bar_area, &obj_dp->cords);
tmp = (uint32_t)ext_dp->act_value * lv_obj_get_width(obj_dp);
tmp = (uint32_t) tmp / (ext_dp->max_value - ext_dp->min_value);
bar_area.x2 = bar_area.x1 + (cord_t) tmp;
lv_pbs_t * style_p = lv_obj_get_style(obj_dp);
lv_draw_rect(&bar_area, mask_p, &style_p->bar, OPA_COVER);
}
/*Draw the object*/
ancestor_design_fp(obj_dp, mask_p, mode);
lv_pb_ext_t * ext_dp = lv_obj_get_ext(obj_dp);
area_t bar_area;
uint32_t tmp;
area_cpy(&bar_area, &obj_dp->cords);
tmp = (uint32_t)ext_dp->act_value * lv_obj_get_width(obj_dp);
tmp = (uint32_t) tmp / (ext_dp->max_value - ext_dp->min_value);
bar_area.x2 = bar_area.x1 + (cord_t) tmp;
lv_pbs_t * style_p = lv_obj_get_style(obj_dp);
lv_draw_rect(&bar_area, mask_p, &style_p->bar, OPA_COVER);
return true;
}

View File

@ -7,7 +7,7 @@
* INCLUDES
*********************/
#include <lvgl/lv_misc/2d.h>
#include <lvgl/lv_misc/area.h>
#include <misc/mem/dyn_mem.h>
#include <misc/mem/linked_list.h>
#include <misc/others/color.h>
@ -173,8 +173,7 @@ void lv_rect_set_fit(lv_obj_t * obj_dp, bool hor_en, bool ver_en)
ext_p->vfit_en = ver_en == false ? 0 : 1;
/*Send a signal to run the paddig calculations*/
lv_obj_t * par_dp = lv_obj_get_parent(obj_dp);
par_dp->signal_f(par_dp, LV_SIGNAL_CHILD_CHG, obj_dp);
obj_dp->signal_f(obj_dp, LV_SIGNAL_CORD_CHG, obj_dp);
}
/*=====================
@ -248,12 +247,13 @@ lv_rects_t * lv_rects_get(lv_rects_builtin_t style, lv_rects_t * copy_p)
**********************/
/**
* Handle the drawing related tasks of the labels
* Handle the drawing related tasks of the rectangles
* @param obj_dp 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_rect_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -278,15 +278,14 @@ static bool lv_rect_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mo
if(area_is_in(mask_p, &area_tmp) == true) return true;
return false;
}
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
opa_t opa = lv_obj_get_opa(obj_dp);
area_t area;
lv_obj_get_cords(obj_dp, &area);
/*Draw the rectangle*/
lv_draw_rect(&area, mask_p, lv_obj_get_style(obj_dp), opa);
/*Draw the rectangle*/
lv_draw_rect(&area, mask_p, lv_obj_get_style(obj_dp), opa);
}
return true;
}

View File

@ -11,6 +11,7 @@
#if USE_LV_TA != 0
#include "lv_ta.h"
#include "../lv_draw/lv_draw.h"
/*********************
* DEFINES
@ -25,14 +26,62 @@
* STATIC PROTOTYPES
**********************/
static bool lv_ta_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode);
static bool lv_ta_label_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode);
static void lv_ta_save_valid_cursor_x(lv_obj_t * obj_dp);
/**********************
* STATIC VARIABLES
**********************/
static lv_tas_t lv_tas_def =
{ /*Create a default style*/ };
{ .pages.bg_rects.objs.color = COLOR_MAKE(0x50, 0x70, 0x90),
.pages.bg_rects.gcolor = COLOR_MAKE(0x70, 0xA0, 0xC0),
.pages.bg_rects.bcolor = COLOR_WHITE,
.pages.bg_rects.bopa = 50,
.pages.bg_rects.bwidth = 2 * LV_STYLE_MULT,
.pages.bg_rects.round = 4 * LV_STYLE_MULT,
.pages.bg_rects.empty = 0,
.pages.bg_rects.hpad = 10 * LV_STYLE_MULT,
.pages.bg_rects.vpad = 10 * LV_STYLE_MULT,
.pages.bg_rects.opad = 5 * LV_STYLE_MULT,
.pages.scrable_rects.objs.color = COLOR_WHITE,
.pages.scrable_rects.gcolor = COLOR_SILVER,
.pages.scrable_rects.bcolor = COLOR_GRAY,
.pages.scrable_rects.bopa = 50,
.pages.scrable_rects.bwidth = 0 * LV_STYLE_MULT,
.pages.scrable_rects.round = 2 * LV_STYLE_MULT,
.pages.scrable_rects.empty = 0,
.pages.scrable_rects.hpad = 10 * LV_STYLE_MULT,
.pages.scrable_rects.vpad = 10 * LV_STYLE_MULT,
.pages.scrable_rects.opad = 5 * LV_STYLE_MULT,
.pages.sb_rects.objs.color = COLOR_BLACK,
.pages.sb_rects.gcolor = COLOR_BLACK,
.pages.sb_rects.bcolor = COLOR_WHITE,
.pages.sb_rects.bopa = 50,
.pages.sb_rects.bwidth = 1 * LV_STYLE_MULT,
.pages.sb_rects.round = 5 * LV_STYLE_MULT,
.pages.sb_rects.empty = 0,
.pages.sb_rects.hpad = 0,
.pages.sb_rects.vpad = 0,
.pages.sb_rects.opad = 0,
.pages.sb_width= 8 * LV_STYLE_MULT,
.pages.sb_opa=50,
.pages.sb_mode = LV_PAGE_SB_MODE_AUTO,
.labels.font = LV_FONT_DEFAULT,
.labels.objs.color = COLOR_MAKE(0x10, 0x18, 0x20),
.labels.letter_space = 2 * LV_STYLE_MULT,
.labels.line_space = 2 * LV_STYLE_MULT,
.labels.mid = 0,
.cursor_color = COLOR_MAKE(0x20, 0x20, 0x20),
.cursor_width = 2 * LV_STYLE_MULT, /*>1 px for visible cursor*/
};
lv_design_f_t ancestor_design_f;
lv_design_f_t label_design_f;
/**********************
* MACROS
@ -69,17 +118,32 @@ lv_obj_t* lv_ta_create(lv_obj_t* par_dp, lv_obj_t * copy_dp)
lv_obj_set_signal_f(new_obj_dp, lv_ta_signal);
lv_obj_set_design_f(new_obj_dp, lv_ta_design);
ext_dp->cursor_valid_x = 0;
ext_dp->cursor_pos = 0;
/*Init the new text area object*/
if(copy_dp == NULL) {
ext_dp->label_dp = lv_label_create(new_obj_dp, NULL);
lv_label_set_text(ext_dp->label_dp, "0123456789 abcdef\nABCDEF\nG\nHIJKLM\n\nnopqrs");
//lv_obj_set_style(ext_dp->label_dp, lv_labels_get(LV_LABELS_TXT, NULL));
// lv_label_set_fixw(ext_dp->label_dp, true);
lv_obj_set_width_us(ext_dp->label_dp, 200);
if(label_design_f == NULL) {
label_design_f = lv_obj_get_design_f(ext_dp->label_dp);
}
lv_obj_set_design_f(ext_dp->label_dp, lv_ta_label_design);
lv_label_set_fixw(ext_dp->label_dp, true);
lv_label_set_text(ext_dp->label_dp, "abc aaaa bbbb ccc\n123\nABC\nxyz\nwww\n007\nalma\n:)\naaaaaa");
lv_page_glue_obj(ext_dp->label_dp, true);
lv_obj_set_click(ext_dp->label_dp, true);
lv_obj_set_style(new_obj_dp, &lv_tas_def);
}
/*Copy an existing object*/
else {
lv_ta_ext_t * copy_ext_dp = lv_obj_get_ext(copy_dp);
ext_dp->label_dp = lv_label_create(new_obj_dp, copy_ext_dp->label_dp);
lv_obj_set_design_f(ext_dp->label_dp, lv_ta_label_design);
lv_page_glue_obj(ext_dp->label_dp, true);
/*Refresh the style when everything is ready*/
lv_obj_set_style(new_obj_dp, lv_obj_get_style(copy_dp));
}
return new_obj_dp;
@ -102,9 +166,23 @@ bool lv_ta_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param)
/* The object can be deleted so check its validity and then
* make the object specific signal handling */
if(valid != false) {
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(obj_dp);
lv_tas_t * tas_p = lv_obj_get_style(obj_dp);
switch(sign) {
case LV_SIGNAL_CLEANUP:
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
lv_obj_del(ta_ext_dp->label_dp);
break;
case LV_SIGNAL_STYLE_CHG:
lv_obj_set_style(ta_ext_dp->label_dp, &tas_p->labels);
lv_obj_set_width(ta_ext_dp->label_dp, lv_obj_get_width(obj_dp) - 2 *
(tas_p->pages.bg_rects.hpad + tas_p->pages.scrable_rects.hpad));
lv_label_set_text(ta_ext_dp->label_dp, NULL);
break;
/*Set the label width according to the text area width*/
case LV_SIGNAL_CORD_CHG:
lv_obj_set_width(ta_ext_dp->label_dp, lv_obj_get_width(obj_dp) - 2 *
(tas_p->pages.bg_rects.hpad + tas_p->pages.scrable_rects.hpad));
lv_label_set_text(ta_ext_dp->label_dp, NULL);
break;
default:
break;
@ -118,10 +196,16 @@ bool lv_ta_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param)
* Setter functions
*====================*/
/**
* Insert a character to the current cursor position
* @param obj_dp pointer to a text area object
* @param c a character
*/
void lv_ta_add_char(lv_obj_t * obj_dp, char c)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
/*Insert the character*/
char buf[LV_TA_MAX_LENGTH];
const char * label_txt = lv_label_get_text(ta_dp->label_dp);
@ -129,15 +213,26 @@ void lv_ta_add_char(lv_obj_t * obj_dp, char c)
buf[ta_dp->cursor_pos] = c;
memcpy(buf+ta_dp->cursor_pos+1, label_txt+ta_dp->cursor_pos, strlen(label_txt) - ta_dp->cursor_pos + 1);
/*Refresh the label*/
lv_label_set_text(ta_dp->label_dp, buf);
/*Move the cursor after the new character*/
lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) + 1);
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(obj_dp);
}
/**
* Insert a text to the current cursor position
* @param obj_dp pointer to a text area object
* @param txt a '\0' terminated string to insert
*/
void lv_ta_add_text(lv_obj_t * obj_dp, const char * txt)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
/*Insert the text*/
char buf[LV_TA_MAX_LENGTH];
const char * label_txt = lv_label_get_text(ta_dp->label_dp);
uint16_t label_len = strlen(label_txt);
@ -147,11 +242,20 @@ void lv_ta_add_text(lv_obj_t * obj_dp, const char * txt)
memcpy(buf+ta_dp->cursor_pos, txt, txt_len);
memcpy(buf+ta_dp->cursor_pos + txt_len, label_txt+ta_dp->cursor_pos, label_len - ta_dp->cursor_pos + 1);
/*Refresh the label*/
lv_label_set_text(ta_dp->label_dp, buf);
/*Move the cursor after the new text*/
lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) + txt_len);
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(obj_dp);
}
/**
* Delete a the left character from the current cursor position
* @param obj_dp pointer to a text area object
*/
void lv_ta_del(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
@ -159,60 +263,163 @@ void lv_ta_del(lv_obj_t * obj_dp)
if(cur_pos == 0) return;
/*Delete a character*/
char buf[LV_TA_MAX_LENGTH];
const char * label_txt = lv_label_get_text(ta_dp->label_dp);
uint16_t label_len = strlen(label_txt);
memcpy(buf, label_txt, cur_pos - 1);
memcpy(buf+cur_pos - 1, label_txt + cur_pos, label_len - cur_pos + 1);
/*Refresh the label*/
lv_label_set_text(ta_dp->label_dp, buf);
/*Move the cursor to the place of the deleted character*/
lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) - 1);
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(obj_dp);
}
/**
* Set the cursor position
* @param obj_dp pointer to a text area object
* @param pos the new cursor position in character index
*/
void lv_ta_set_cursor_pos(lv_obj_t * obj_dp, uint16_t pos)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
ta_dp->cursor_pos = pos;
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(obj_dp);
uint16_t txt_len = strlen(lv_label_get_text(ta_ext_dp->label_dp));
if(pos > txt_len) pos = txt_len;
ta_ext_dp->cursor_pos = pos;
/*Position the label to make the cursor visible*/
lv_obj_t * label_par_dp = lv_obj_get_parent(ta_ext_dp->label_dp);
point_t cur_pos;
lv_tas_t * tas_p = lv_obj_get_style(obj_dp);
const font_t * font_p = font_get(tas_p->labels.font);
lv_label_get_letter_pos(ta_ext_dp->label_dp, pos, &cur_pos);
/*Check the top*/
if(lv_obj_get_y(label_par_dp) + cur_pos.y < 0) {
lv_obj_set_y(label_par_dp, - cur_pos.y);
}
/*Check the bottom*/
if(lv_obj_get_y(label_par_dp) + cur_pos.y + font_get_height(font_p) > lv_obj_get_height(obj_dp)) {
lv_obj_set_y(label_par_dp, -(cur_pos.y - lv_obj_get_height(obj_dp) +
font_get_height(font_p) + tas_p->pages.scrable_rects.vpad * 2));
}
lv_obj_inv(obj_dp);
}
void lv_ta_cursor_down(lv_obj_t * obj_dp)
/**
* Move the cursor one character right
* @param obj_dp pointer to a text area object
*/
void lv_ta_cursor_right(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
point_t pos;
uint16_t cp = lv_ta_get_cursor_pos(obj_dp);
cp++;
lv_ta_set_cursor_pos(obj_dp, cp);
lv_label_get_letter_pos(ta_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos);
lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp);
const font_t * font_p = font_get(labels_p->font);
pos.y += font_get_height(font_p) + labels_p->line_space + 1;
uint16_t new_cur_pos = lv_label_get_letter_on(ta_dp->label_dp, &pos);
lv_ta_set_cursor_pos(obj_dp, new_cur_pos);
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(obj_dp);
}
void lv_ta_cursor_up(lv_obj_t * obj_dp)
/**
* Move the cursor one character left
* @param obj_dp pointer to a text area object
*/
void lv_ta_cursor_left(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
uint16_t cp = lv_ta_get_cursor_pos(obj_dp);
if(cp > 0) {
cp--;
lv_ta_set_cursor_pos(obj_dp, cp);
/*It is a valid x step so save it*/
lv_ta_save_valid_cursor_x(obj_dp);
}
}
/**
* Move the cursor one line down
* @param obj_dp pointer to a text area object
*/
void lv_ta_cursor_down(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(obj_dp);
point_t pos;
lv_label_get_letter_pos(ta_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos);
/*Get the position of the current letter*/
lv_label_get_letter_pos(ta_ext_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos);
lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp);
/*Increment the y with one line and keep the valid x*/
lv_labels_t * labels_p = lv_obj_get_style(ta_ext_dp->label_dp);
const font_t * font_p = font_get(labels_p->font);
pos.y += font_get_height(font_p) + labels_p->line_space + 1;
pos.x = ta_ext_dp->cursor_valid_x;
/*Do not go below he last line*/
if(pos.y < lv_obj_get_height(ta_ext_dp->label_dp)) {
/*Get the letter index on the new cursor position and set it*/
uint16_t new_cur_pos = lv_label_get_letter_on(ta_ext_dp->label_dp, &pos);
lv_ta_set_cursor_pos(obj_dp, new_cur_pos);
}
}
/**
* Move the cursor one line up
* @param obj_dp pointer to a text area object
*/
void lv_ta_cursor_up(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(obj_dp);
point_t pos;
/*Get the position of the current letter*/
lv_label_get_letter_pos(ta_ext_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos);
/*Decrement the y with one line and keep the valid x*/
lv_labels_t * labels_p = lv_obj_get_style(ta_ext_dp->label_dp);
const font_t * font_p = font_get(labels_p->font);
pos.y -= font_get_height(font_p) + labels_p->line_space - 1;
pos.x = ta_ext_dp->cursor_valid_x;
uint16_t new_cur_pos = lv_label_get_letter_on(ta_dp->label_dp, &pos);
/*Get the letter index on the new cursor position and set it*/
uint16_t new_cur_pos = lv_label_get_letter_on(ta_ext_dp->label_dp, &pos);
lv_ta_set_cursor_pos(obj_dp, new_cur_pos);
}
/*=====================
* Getter functions
*====================*/
/**
* Get the text of the i the text area
* @param obj_dp obj_dp pointer to a text area object
* @return pointer to the text
*/
const char * lv_ta_get_text(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
return lv_label_get_text(ta_dp->label_dp);
}
/**
* Get the current cursor position in character index
* @param obj_dp pointer to a text area object
* @return the cursor position
*/
uint16_t lv_ta_get_cursor_pos(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
return ta_dp->cursor_pos;
}
/**
* Return with a pointer to a built-in style and/or copy it to a variable
* @param style a style name from lv_tas_builtin_t enum
@ -238,12 +445,6 @@ lv_tas_t * lv_tas_get(lv_tas_builtin_t style, lv_tas_t * copy_p)
return style_p;
}
uint16_t lv_ta_get_cursor_pos(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
return ta_dp->cursor_pos;
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -255,7 +456,8 @@ uint16_t lv_ta_get_cursor_pos(lv_obj_t * obj_dp)
* @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_MAIN: 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_ta_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
@ -263,33 +465,66 @@ static bool lv_ta_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return ancestor_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the object*/
ancestor_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design_f(obj_dp, mask_p, mode);
}
/*Draw the object*/
ancestor_design_f(obj_dp, mask_p, mode);
lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp);
uint16_t cur_pos = lv_ta_get_cursor_pos(obj_dp);
point_t letter_pos;
lv_label_get_letter_pos(ta_dp->label_dp, cur_pos, &letter_pos);
area_t cur_area;
lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp);
cur_area.x1 = letter_pos.x + ta_dp->label_dp->cords.x1 - 2;
cur_area.y1 = letter_pos.y + ta_dp->label_dp->cords.y1;
cur_area.x2 = letter_pos.x + ta_dp->label_dp->cords.x1 + 2;
cur_area.y2 = letter_pos.y + ta_dp->label_dp->cords.y1 + font_get_height(font_get(labels_p->font));
lv_rects_t rects;
lv_rects_get(LV_RECTS_DEF, &rects);
rects.round = 0;
rects.bwidth = 0;
rects.objs.color = COLOR_RED;
rects.gcolor = COLOR_RED;
lv_draw_rect(&cur_area, mask_p, &rects, OPA_COVER);
return true;
}
static bool lv_ta_label_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return label_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the object*/
label_design_f(obj_dp, mask_p, mode);
} else if(mode == LV_DESIGN_DRAW_POST) {
label_design_f(obj_dp, mask_p, mode);
/*Draw the cursor too*/
lv_obj_t * ta_dp = lv_obj_get_parent(lv_obj_get_parent(obj_dp));
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(ta_dp);
lv_tas_t * tas_p = lv_obj_get_style(ta_dp);
uint16_t cur_pos = lv_ta_get_cursor_pos(ta_dp);
point_t letter_pos;
lv_label_get_letter_pos(obj_dp, cur_pos, &letter_pos);
area_t cur_area;
lv_labels_t * labels_p = lv_obj_get_style(ta_ext_dp->label_dp);
cur_area.x1 = letter_pos.x + obj_dp->cords.x1 - (tas_p->cursor_width >> 1);
cur_area.y1 = letter_pos.y + obj_dp->cords.y1;
cur_area.x2 = letter_pos.x + obj_dp->cords.x1 + (tas_p->cursor_width >> 1);
cur_area.y2 = letter_pos.y + obj_dp->cords.y1 + font_get_height(font_get(labels_p->font));
lv_rects_t cur_rects;
lv_rects_get(LV_RECTS_DEF, &cur_rects);
cur_rects.round = 0;
cur_rects.bwidth = 0;
cur_rects.objs.color = tas_p->cursor_color;
cur_rects.gcolor = tas_p->cursor_color;
lv_draw_rect(&cur_area, mask_p, &cur_rects, OPA_COVER);
}
return true;
}
/**
* Save the cursor x position as valid. It is important when jumping up/down to a shorter line
* @param obj_dp pointer to a text area object
*/
static void lv_ta_save_valid_cursor_x(lv_obj_t * obj_dp)
{
lv_ta_ext_t * ta_ext_dp = lv_obj_get_ext(obj_dp);
point_t cur_pos;
lv_label_get_letter_pos(ta_ext_dp->label_dp, ta_ext_dp->cursor_pos, &cur_pos);
ta_ext_dp->cursor_valid_x = cur_pos.x;
}
#endif

View File

@ -30,6 +30,8 @@ typedef struct
lv_pages_t pages; /*Style of ancestor*/
/*New style element for this type */
lv_labels_t labels;
color_t cursor_color;
cord_t cursor_width;
uint8_t cursor_show :1;
}lv_tas_t;
@ -45,6 +47,7 @@ typedef struct
lv_page_ext_t page; /*Ext. of ancestor*/
/*New data for this type */
lv_obj_t * label_dp;
cord_t cursor_valid_x;
uint16_t cursor_pos;
}lv_ta_ext_t;
@ -59,6 +62,8 @@ void lv_ta_add_char(lv_obj_t * obj_dp, char c);
void lv_ta_add_text(lv_obj_t * obj_dp, const char * txt);
void lv_ta_del(lv_obj_t * obj_dp);
void lv_ta_set_cursor_pos(lv_obj_t * obj_dp, uint16_t pos);
void lv_ta_cursor_right (lv_obj_t * obj_dp);
void lv_ta_cursor_left(lv_obj_t * obj_dp);
void lv_ta_cursor_down(lv_obj_t * obj_dp);
void lv_ta_cursor_up(lv_obj_t * obj_dp);