From ee80e1f98a7c3dd627d8e99d17461b96d56903c5 Mon Sep 17 00:00:00 2001 From: Gabor Date: Fri, 7 Oct 2016 17:33:35 +0200 Subject: [PATCH] lv_win added + bugfixes --- lv_misc/text.c | 2 +- lv_obj/lv_obj.h | 6 +- lv_objx/lv_img.c | 2 +- lv_objx/lv_line.c | 24 +-- lv_objx/lv_rect.c | 8 +- lv_objx/lv_ta.c | 35 +++-- lv_objx/lv_win.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++ lv_objx/lv_win.h | 80 ++++++++++ 8 files changed, 507 insertions(+), 38 deletions(-) create mode 100644 lv_objx/lv_win.c create mode 100644 lv_objx/lv_win.h diff --git a/lv_misc/text.c b/lv_misc/text.c index a628e6f72..31128cafd 100644 --- a/lv_misc/text.c +++ b/lv_misc/text.c @@ -66,7 +66,7 @@ uint16_t txt_get_next_line(const char * txt, const font_t * font_p, /*If the txt is too long then finish, this is the line end*/ if(act_l > max_l) { /*If already a break character is found, then break there*/ - if(last_break != TXT_NO_BREAK_FOUND) { + if(last_break != TXT_NO_BREAK_FOUND && txt_is_break_char(txt[i]) == false) { i = last_break; } diff --git a/lv_obj/lv_obj.h b/lv_obj/lv_obj.h index 732d0035d..d513c9e25 100644 --- a/lv_obj/lv_obj.h +++ b/lv_obj/lv_obj.h @@ -59,7 +59,7 @@ typedef enum LV_DESIGN_COVER_CHK, }lv_design_mode_t; -typedef bool (* lv_design_f_t) (struct __lv_obj_t * obj, const area_t * mask_p, lv_design_mode_t mode); +typedef bool (* lv_design_f_t) (struct __LV_OBJ_T * obj, const area_t * mask_p, lv_design_mode_t mode); typedef enum { @@ -75,11 +75,11 @@ typedef enum LV_SIGNAL_STYLE_CHG, }lv_signal_t; -typedef bool (* lv_signal_f_t) (struct __lv_obj_t * obj, lv_signal_t sign, void * param); +typedef bool (* lv_signal_f_t) (struct __LV_OBJ_T * obj, lv_signal_t sign, void * param); typedef struct __LV_OBJ_T { - struct __lv_obj_t * par; + struct __LV_OBJ_T * par; ll_dsc_t child_ll; area_t cords; diff --git a/lv_objx/lv_img.c b/lv_objx/lv_img.c index 72f7d7cd5..be5ff2614 100644 --- a/lv_objx/lv_img.c +++ b/lv_objx/lv_img.c @@ -54,7 +54,7 @@ lv_obj_t * lv_img_create(lv_obj_t * par, lv_obj_t * copy) lv_obj_t * new_img = NULL; /*Create a basic object*/ - new_img = lv_obj_create(par, NULL); + new_img = lv_obj_create(par, copy); /*Extend the basic object to image object*/ lv_obj_alloc_ext(new_img, sizeof(lv_img_ext_t)); diff --git a/lv_objx/lv_line.c b/lv_objx/lv_line.c index 7694f1264..a1f682efa 100644 --- a/lv_objx/lv_line.c +++ b/lv_objx/lv_line.c @@ -70,7 +70,7 @@ lv_obj_t * lv_line_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new rectangle*/ if(copy == NULL) { ext->point_num = 0; - ext->point_p = NULL; + ext->point_array = NULL; ext->auto_size = 1; ext->y_inv = 0; ext->upscale = 0; @@ -82,7 +82,7 @@ lv_obj_t * lv_line_create(lv_obj_t * par, lv_obj_t * copy) lv_line_set_y_inv(new_line,lv_line_get_y_inv(copy)); lv_line_set_auto_size(new_line,lv_line_get_auto_size(copy)); lv_line_set_upscale(new_line,lv_line_get_upscale(copy)); - lv_line_set_points(new_line, LV_EA(copy, lv_line_ext_t)->point_p, + lv_line_set_points(new_line, LV_EA(copy, lv_line_ext_t)->point_array, LV_EA(copy, lv_line_ext_t)->point_num); } @@ -129,7 +129,7 @@ bool lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param) void lv_line_set_points(lv_obj_t * line, const point_t * point_a, uint16_t point_num) { lv_line_ext_t * ext = lv_obj_get_ext(line); - ext->point_p = point_a; + ext->point_array = point_a; ext->point_num = point_num; uint8_t us = 1; @@ -165,7 +165,7 @@ void lv_line_set_auto_size(lv_obj_t * line, bool autosize) /*Refresh the object*/ if(autosize != false) { - lv_line_set_points(line, ext->point_p, ext->point_num); + lv_line_set_points(line, ext->point_array, ext->point_num); } } @@ -197,7 +197,7 @@ void lv_line_set_upscale(lv_obj_t * line, bool unscale) ext->upscale = unscale == false ? 0 : 1; /*Refresh to point to handle auto size*/ - lv_line_set_points(line, ext->point_p, ext->point_num); + lv_line_set_points(line, ext->point_array, ext->point_num); } /*===================== @@ -300,7 +300,7 @@ static bool lv_line_design(lv_obj_t * line, const area_t * mask, lv_design_mode_ else if(mode == LV_DESIGN_DRAW_MAIN) { lv_line_ext_t * ext = lv_obj_get_ext(line); - if(ext->point_num == 0 || ext->point_p == NULL) return false; + if(ext->point_num == 0 || ext->point_array == NULL) return false; lv_lines_t * lines = lv_obj_get_style(line); @@ -321,15 +321,15 @@ static bool lv_line_design(lv_obj_t * line, const area_t * mask, lv_design_mode_ /*Read all pints and draw the lines*/ for (i = 0; i < ext->point_num - 1; i++) { - p1.x = ext->point_p[i].x * us + x_ofs; - p2.x = ext->point_p[i + 1].x * us + x_ofs; + p1.x = ext->point_array[i].x * us + x_ofs; + p2.x = ext->point_array[i + 1].x * us + x_ofs; if(ext->y_inv == 0) { - p1.y = ext->point_p[i].y * us + y_ofs; - p2.y = ext->point_p[i + 1].y * us + y_ofs; + p1.y = ext->point_array[i].y * us + y_ofs; + p2.y = ext->point_array[i + 1].y * us + y_ofs; } else { - p1.y = h - ext->point_p[i].y * us + y_ofs; - p2.y = h - ext->point_p[i + 1].y * us + y_ofs; + p1.y = h - ext->point_array[i].y * us + y_ofs; + p2.y = h - ext->point_array[i + 1].y * us + y_ofs; } lv_draw_line(&p1, &p2, mask, lines, opa); } diff --git a/lv_objx/lv_rect.c b/lv_objx/lv_rect.c index 357f20744..326a86960 100644 --- a/lv_objx/lv_rect.c +++ b/lv_objx/lv_rect.c @@ -87,10 +87,10 @@ lv_obj_t * lv_rect_create(lv_obj_t * par, lv_obj_t * copy) } /*Copy an existing object*/ else { - lv_rect_ext_t * ori_rect_ext = lv_obj_get_ext(copy); - rect_ext->hfit_en = ori_rect_ext->hfit_en; - rect_ext->vfit_en = ori_rect_ext->vfit_en; - rect_ext->layout = ori_rect_ext->layout; + lv_rect_ext_t * copy_ext = lv_obj_get_ext(copy); + rect_ext->hfit_en = copy_ext->hfit_en; + rect_ext->vfit_en = copy_ext->vfit_en; + rect_ext->layout = copy_ext->layout; } return new_rect; diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 80c4fd564..4e84d43b8 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -26,7 +26,7 @@ * STATIC PROTOTYPES **********************/ static bool lv_ta_design(lv_obj_t * ta, const area_t * mask, lv_design_mode_t mode); -static bool lv_ta_label_design(lv_obj_t * label, const area_t * mask, lv_design_mode_t mode); +static bool lv_ta_scrling_design(lv_obj_t * scrling, const area_t * mask, lv_design_mode_t mode); static void lv_ta_save_valid_cursor_x(lv_obj_t * ta); static void lv_tas_init(void); @@ -36,7 +36,7 @@ static void lv_tas_init(void); static lv_tas_t lv_tas_def; lv_design_f_t ancestor_design_f; -lv_design_f_t label_design_f; +lv_design_f_t scrling_design_f; /********************** * MACROS @@ -79,10 +79,10 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new text area object*/ if(copy == NULL) { ext->label = lv_label_create(new_ta, NULL); - if(label_design_f == NULL) { - label_design_f = lv_obj_get_design_f(ext->label); + if(scrling_design_f == NULL) { + scrling_design_f = lv_obj_get_design_f(ext->page.scrolling); } - lv_obj_set_design_f(ext->label, lv_ta_label_design); + lv_obj_set_design_f(ext->page.scrolling, lv_ta_scrling_design); lv_label_set_fixw(ext->label, true); lv_label_set_text(ext->label, "abc aaaa bbbb ccc\n123\nABC\nxyz\nwww\n007\nalma\n:)\naaaaaa"); lv_page_glue_obj(ext->label, true); @@ -91,9 +91,9 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy) } /*Copy an existing object*/ else { + lv_obj_set_design_f(ext->page.scrolling, lv_ta_scrling_design); lv_ta_ext_t * copy_ext = lv_obj_get_ext(copy); ext->label = lv_label_create(new_ta, copy_ext->label); - lv_obj_set_design_f(ext->label, lv_ta_label_design); lv_page_glue_obj(ext->label, true); /*Refresh the style when everything is ready*/ @@ -437,7 +437,7 @@ static bool lv_ta_design(lv_obj_t * ta, const area_t * masp, lv_design_mode_t mo } /** - * An extended label design. Calls the normal label design function and it draws a cursor. + * An extended scrolling design of the page. Calls the normal design function and it draws a cursor. * @param label pointer to a text area 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 @@ -446,33 +446,33 @@ static bool lv_ta_design(lv_obj_t * ta, const area_t * masp, lv_design_mode_t mo * LV_DESIGN_DRAW_POST: drawing after every children are drawn * @return return true/false, depends on 'mode' */ -static bool lv_ta_label_design(lv_obj_t * label, const area_t * mask, lv_design_mode_t mode) +static bool lv_ta_scrling_design(lv_obj_t * scrling, const area_t * mask, 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(label, mask, mode); + return scrling_design_f(scrling, mask, mode); } else if(mode == LV_DESIGN_DRAW_MAIN) { /*Draw the object*/ - label_design_f(label, mask, mode); + scrling_design_f(scrling, mask, mode); } else if(mode == LV_DESIGN_DRAW_POST) { - label_design_f(label, mask, mode); + scrling_design_f(scrling, mask, mode); /*Draw the cursor too*/ - lv_obj_t * ta = lv_obj_get_parent(lv_obj_get_parent(label)); + lv_obj_t * ta = lv_obj_get_parent(scrling); lv_ta_ext_t * ta_ext = lv_obj_get_ext(ta); lv_tas_t * ta_style = lv_obj_get_style(ta); if(ta_style->cursor_show != 0) { uint16_t cur_pos = lv_ta_get_cursor_pos(ta); point_t letter_pos; - lv_label_get_letter_pos(label, cur_pos, &letter_pos); + lv_label_get_letter_pos(ta_ext->label, cur_pos, &letter_pos); area_t cur_area; lv_labels_t * labels_p = lv_obj_get_style(ta_ext->label); - cur_area.x1 = letter_pos.x + label->cords.x1 - (ta_style->cursor_width >> 1); - cur_area.y1 = letter_pos.y + label->cords.y1; - cur_area.x2 = letter_pos.x + label->cords.x1 + (ta_style->cursor_width >> 1); - cur_area.y2 = letter_pos.y + label->cords.y1 + font_get_height(font_get(labels_p->font)); + cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - (ta_style->cursor_width >> 1); + cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1; + cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + (ta_style->cursor_width >> 1); + cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + font_get_height(font_get(labels_p->font)); lv_rects_t cur_rects; lv_rects_get(LV_RECTS_DEF, &cur_rects); @@ -512,5 +512,6 @@ static void lv_tas_init(void) lv_tas_def.cursor_color = COLOR_MAKE(0x10, 0x10, 0x10); lv_tas_def.cursor_width = 2 * LV_STYLE_MULT; /*>1 px for visible cursor*/ + lv_tas_def.cursor_show = 1; } #endif diff --git a/lv_objx/lv_win.c b/lv_objx/lv_win.c new file mode 100644 index 000000000..3b0d72c0b --- /dev/null +++ b/lv_objx/lv_win.c @@ -0,0 +1,388 @@ +/** + * @file lv_win.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_conf.h" +#if USE_LV_WIN != 0 + +#include "lv_win.h" + +/********************* + * DEFINES + *********************/ +#define LV_WIN_CTRL_BTN_DEF_W (30 * LV_DOWNSCALE) +#define LV_WIN_CTRL_BTN_DEF_H (30 * LV_DOWNSCALE) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +#if 0 /*Not used*/ +static bool lv_win_design(lv_obj_t * win, const area_t * mask, lv_design_mode_t mode); +#endif +static void lv_wins_init(void); +static void lv_win_realign(lv_obj_t * win); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_wins_t lv_wins_def; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/*----------------- + * Create function + *-----------------*/ + +/** + * Create a window objects + * @param par pointer to an object, it will be the parent of the new window + * @param copy pointer to a window object, if not NULL then the new object will be copied from it + * @return pointer to the created window + */ +lv_obj_t * lv_win_create(lv_obj_t * par, lv_obj_t * copy) +{ + /*Create the ancestor object*/ + lv_obj_t * new_win = lv_obj_create(par, copy); + dm_assert(new_win); + + /*Allocate the object type specific extended data*/ + lv_win_ext_t * ext = lv_obj_alloc_ext(new_win, sizeof(lv_win_ext_t)); + dm_assert(ext); + + /*The signal and design functions are not copied so set them here*/ + lv_obj_set_signal_f(new_win, lv_win_signal); + /* The design function is not changed + lv_obj_set_design_f(new_obj, lv_win_design); */ + + lv_obj_set_size(new_win, LV_HOR_RES, LV_VER_RES); + + /*Init the new window object*/ + if(copy == NULL) { + /*Create a holder for the header*/ + ext->header = lv_rect_create(new_win, NULL); + lv_rect_set_fit(ext->header, false, true); + + /*Create a title on the header*/ + ext->title = lv_label_create(ext->header, NULL); + lv_label_set_text(ext->title,"My title"); + + /*Create a holder for the control buttons*/ + ext->ctrl_holder = lv_rect_create(ext->header, NULL); + lv_rect_set_fit(ext->ctrl_holder, true, true); + lv_rect_set_layout(ext->ctrl_holder, LV_RECT_LAYOUT_ROW_M); + + /*Create a page for the content*/ + ext->content = lv_page_create(new_win, NULL); + + lv_obj_set_style(new_win, lv_wins_get(LV_WINS_DEF, NULL)); + + lv_win_realign(new_win); + } + /*Copy an existing object*/ + else { + lv_win_ext_t * copy_ext = lv_obj_get_ext(copy); + /*Create the objects*/ + ext->header = lv_rect_create(new_win, copy_ext->header); + ext->title = lv_label_create(ext->header, copy_ext->title); + ext->ctrl_holder = lv_rect_create(ext->header, copy_ext->ctrl_holder); + ext->content = lv_page_create(new_win, copy_ext->content); + + /*Copy the control buttons*/ + lv_obj_t * child; + lv_obj_t * cbtn; + child = lv_obj_get_child(copy_ext->ctrl_holder, NULL); + while(child != NULL) { + cbtn = lv_btn_create(ext->ctrl_holder, child); + lv_img_create(cbtn, lv_obj_get_child(child, NULL)); + child = lv_obj_get_child(copy_ext->ctrl_holder, child); + } + + lv_obj_set_style(new_win, lv_obj_get_style(copy)); + + lv_win_realign(new_win); + } + + return new_win; +} + +/** + * Signal function of the window + * @param win pointer to a window object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return true: the object is still valid (not deleted), false: the object become invalid + */ +bool lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param) +{ + bool valid; + + /* Include the ancient signal function */ + valid = lv_obj_signal(win, sign, param); + lv_win_ext_t * ext = lv_obj_get_ext(win); + lv_wins_t * style = lv_obj_get_style(win); + lv_obj_t * child; + + + /* The object can be deleted so check its validity and then + * make the object specific signal handling */ + if(valid != false) { + switch(sign) { + case LV_SIGNAL_CLEANUP: + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + break; + case LV_SIGNAL_STYLE_CHG: + lv_obj_set_style(ext->content, &style->content); + lv_obj_set_style(ext->ctrl_holder, &style->ctrl_holder); + lv_obj_set_style(ext->title, &style->title); + lv_obj_set_style(ext->header, &style->header); + + /*Refresh the style of all control buttons*/ + child = lv_obj_get_child(ext->ctrl_holder, NULL); + while(child != NULL) { + lv_obj_set_style(child, &style->ctrl_btn); + /*Refresh the image style too*/ + lv_obj_set_style(lv_obj_get_child(child, NULL), &style->ctrl_img); + child = lv_obj_get_child(ext->ctrl_holder, child); + } + break; + case LV_SIGNAL_CHILD_CHG: + /*If a child added move it to the 'content' object*/ + /*(A window can be only 2 children: the header and the content)*/ + child = lv_obj_get_child(win, NULL); + if(ext->content != NULL && ext->header != NULL && + child != ext->content && child != ext->header && + param != NULL) { + lv_obj_set_parent(param, ext->content); + } + break; + case LV_SIGNAL_CORD_CHG: + if(area_get_width(param) != lv_obj_get_width(win) || + area_get_height(param) != lv_obj_get_height(win)) { + lv_win_realign(win); + } + break; + default: + break; + } + } + + return valid; +} + +/*===================== + * Setter functions + *====================*/ + +/** + * Add control button to the header of the window + * @param win pointer to a window object + * @param img_path path of an image on the control button + * @param rel_action a function pointer to call when the button is released + * @return pointer to the created button object + */ +lv_obj_t * lv_win_add_ctrl_btn(lv_obj_t * win, const char * img_path, bool (*rel_action)(lv_obj_t *, lv_dispi_t *)) +{ + lv_win_ext_t * ext = lv_obj_get_ext(win); + lv_wins_t * style = lv_obj_get_style(win); + + lv_obj_t * btn = lv_btn_create(ext->ctrl_holder, NULL); + lv_obj_set_style(btn, &style->ctrl_btn); + lv_obj_set_size(btn, style->ctrl_btn_w, style->ctrl_btn_h); + lv_btn_set_rel_action(btn, rel_action); + lv_obj_t * img = lv_img_create(btn, NULL); + lv_obj_set_click(img, false); + lv_obj_set_style(img, &style->ctrl_img); + lv_img_set_file(img, img_path); + + lv_win_realign(win); + + return btn; +} + +/** + * Set the title of a window + * @param win pointer to a window object + * @param title string of the new title + */ +void lv_win_set_title(lv_obj_t * win, const char * title) +{ + lv_win_ext_t * ext = lv_obj_get_ext(win); + + lv_label_set_text(ext->title, title); + lv_win_realign(win); +} + +/*===================== + * Getter functions + *====================*/ + +/** + * Return with a pointer to a built-in style and/or copy it to a variable + * @param style a style name from lv_wins_builtin_t enum + * @param copy_p copy the style to this variable. (NULL if unused) + * @return pointer to an lv_wins_t style + */ +lv_wins_t * lv_wins_get(lv_wins_builtin_t style, lv_wins_t * copy) +{ + static bool style_inited = false; + + /*Make the style initialization if it is not done yet*/ + if(style_inited == false) { + lv_wins_init(); + style_inited = true; + } + + lv_wins_t *style_p; + + switch(style) { + case LV_WINS_DEF: + style_p = &lv_wins_def; + break; + default: + style_p = &lv_wins_def; + } + + if(copy != NULL) { + if(style_p != NULL) memcpy(copy, style_p, sizeof(lv_wins_t)); + else memcpy(copy, &lv_wins_def, sizeof(lv_wins_t)); + } + + return style_p; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#if 0 /*Not used*/ +/** + * Handle the drawing related tasks of the windows + * @param win 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_win_design(lv_obj_t * win, const area_t * mask, lv_design_mode_t mode) +{ + 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) { + /*Draw the object*/ + + } else if (mode == LV_DESIGN_DRAW_POST) { + /*Draw after all children is drawn*/ + + } + + + + return true; +} +#endif + +/** + * Initialize the window styles + */ +static void lv_wins_init(void) +{ + /*Transparent background. It will be always covered*/ + lv_objs_get(LV_OBJS_TRANSP, &lv_wins_def.bg); + + lv_pages_get(LV_PAGES_DEF, &lv_wins_def.content); + lv_wins_def.content.bg_rects.objs.color = COLOR_WHITE; + lv_wins_def.content.bg_rects.gcolor = COLOR_WHITE; + lv_wins_def.content.bg_rects.bwidth = 1 * LV_STYLE_MULT; + lv_wins_def.content.bg_rects.bcolor = COLOR_GRAY; + lv_wins_def.content.bg_rects.round = 0; + lv_wins_def.content.bg_rects.hpad = 0; + lv_wins_def.content.bg_rects.vpad = 0; + + /*Styles for the header*/ + lv_rects_get(LV_RECTS_DEF, &lv_wins_def.header); + lv_wins_def.header.hpad = 5 * LV_STYLE_MULT; + lv_wins_def.header.vpad = 5 * LV_STYLE_MULT; + lv_wins_def.header.objs.color = COLOR_MAKE(0x30, 0x40, 0x50); + lv_wins_def.header.gcolor = COLOR_MAKE(0x30, 0x40, 0x50); + lv_wins_def.header.bwidth = 0; + lv_wins_def.header.round = 0; + + lv_rects_get(LV_RECTS_TRANSP, &lv_wins_def.ctrl_holder); + lv_wins_def.ctrl_holder.hpad = 0; + lv_wins_def.ctrl_holder.vpad = 0; + lv_wins_def.ctrl_holder.opad = 10 * LV_STYLE_MULT; + + lv_btns_get(LV_BTNS_DEF, &lv_wins_def.ctrl_btn); + lv_wins_def.ctrl_btn.bcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0xD0, 0xE0, 0xF0); + lv_wins_def.ctrl_btn.mcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_wins_def.ctrl_btn.gcolor[LV_BTN_STATE_REL] = COLOR_MAKE(0x30, 0x40, 0x50); + lv_wins_def.ctrl_btn.rects.bopa = 70; + lv_wins_def.ctrl_btn.rects.bwidth = 2 * LV_STYLE_MULT; + lv_wins_def.ctrl_btn.rects.round = LV_RECT_CIRCLE; + + lv_imgs_get(LV_IMGS_DEF, &lv_wins_def.ctrl_img); + lv_wins_def.ctrl_img.recolor_opa = OPA_50; + lv_wins_def.ctrl_img.objs.color = COLOR_WHITE; + + lv_labels_get(LV_LABELS_TITLE, &lv_wins_def.title); + lv_wins_def.title.objs.color = COLOR_MAKE(0xD0, 0xE0, 0xF0); + lv_wins_def.title.letter_space = 1 * LV_STYLE_MULT; + lv_wins_def.title.line_space = 1 * LV_STYLE_MULT; + + lv_wins_def.ctrl_btn_w = LV_WIN_CTRL_BTN_DEF_W; + lv_wins_def.ctrl_btn_h = LV_WIN_CTRL_BTN_DEF_H; +} + +/** + * Realign the building elements of a window + * @param win pointer to window object + */ +static void lv_win_realign(lv_obj_t * win) +{ + lv_win_ext_t * ext = lv_obj_get_ext(win); + lv_wins_t * style = lv_obj_get_style(win); + + if(ext->content == NULL || ext->ctrl_holder == NULL || ext->header == NULL || ext->title == NULL) return; + + lv_obj_t * cbtn; + /*Refresh the style of all control buttons*/ + cbtn = lv_obj_get_child(ext->ctrl_holder, NULL); + while(cbtn != NULL) { + lv_obj_set_size(cbtn, style->ctrl_btn_w, style->ctrl_btn_h); + cbtn = lv_obj_get_child(ext->ctrl_holder, cbtn); + } + + lv_obj_set_width(ext->header, lv_obj_get_width(win)); + lv_obj_set_size(ext->content, lv_obj_get_width(win), lv_obj_get_height(win) - lv_obj_get_height(ext->header)); + + /*Align the higher object first to make the correct header size first*/ + if(lv_obj_get_height(ext->title) > lv_obj_get_height(ext->ctrl_holder)) { + lv_obj_align(ext->title, NULL, LV_ALIGN_IN_LEFT_MID, style->header.hpad, 0); + lv_obj_align(ext->ctrl_holder, NULL, LV_ALIGN_IN_RIGHT_MID, -style->header.hpad, 0); + } else { + lv_obj_align(ext->ctrl_holder, NULL, LV_ALIGN_IN_RIGHT_MID, -style->header.hpad, 0); + lv_obj_align(ext->title, NULL, LV_ALIGN_IN_LEFT_MID, style->header.hpad, 0); + } + + lv_obj_set_pos_us(ext->header, 0, 0); + lv_obj_align_us(ext->content, ext->header, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0); + +} +#endif diff --git a/lv_objx/lv_win.h b/lv_objx/lv_win.h new file mode 100644 index 000000000..3846bd69a --- /dev/null +++ b/lv_objx/lv_win.h @@ -0,0 +1,80 @@ +/** + * @file lv_win.h + * + */ + +#ifndef LV_WIN_H +#define LV_WIN_H + +/********************* + * INCLUDES + *********************/ +#include "lv_conf.h" +#if USE_LV_WIN != 0 + +#include "../lv_obj/lv_obj.h" +#include "lv_rect.h" +#include "lv_btn.h" +#include "lv_label.h" +#include "lv_img.h" +#include "lv_page.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Style of window*/ +typedef struct +{ + lv_objs_t bg; /*Style of ancestor*/ + /*New style element for this type */ + /*Header settings*/ + lv_rects_t header; + lv_labels_t title; + lv_rects_t ctrl_holder; + lv_btns_t ctrl_btn; + lv_imgs_t ctrl_img; + cord_t ctrl_btn_w; + cord_t ctrl_btn_h; + /*Content settings*/ + lv_pages_t content; +}lv_wins_t; + +/*Built-in styles of window*/ +typedef enum +{ + LV_WINS_DEF, +}lv_wins_builtin_t; + +/*Data of window*/ +typedef struct +{ + /*Inherited from 'base_obj' so there is no ext. data*/ /*Ext. of ancestor*/ + /*New data for this type */ + lv_obj_t * header; + lv_obj_t * title; + lv_obj_t * ctrl_holder; + lv_obj_t * content; +}lv_win_ext_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_obj_t * lv_win_create(lv_obj_t * par, lv_obj_t * copy); +bool lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param); +lv_wins_t * lv_wins_get(lv_wins_builtin_t style, lv_wins_t * copy); + +lv_obj_t * lv_win_add_ctrl_btn(lv_obj_t * win, const char * img, bool (*rel_action)(lv_obj_t *, lv_dispi_t *)); +void lv_win_set_title(lv_obj_t * win, const char * title); + +/********************** + * MACROS + **********************/ + +#endif + +#endif