diff --git a/lv_conf_templ.h b/lv_conf_templ.h index e8d83641be..1c9b4ba60b 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -262,6 +262,9 @@ /*Button (dependencies: lv_cont*/ #define USE_LV_BTN 1 +/*Image Button (dependencies: lv_btn*/ +#define USE_LV_IMGBTN 1 + /*Button matrix (dependencies: -)*/ #define USE_LV_BTNM 1 diff --git a/lv_objx/lv_btn.c b/lv_objx/lv_btn.c index bf5fa0d786..2adcac2f2c 100644 --- a/lv_objx/lv_btn.c +++ b/lv_objx/lv_btn.c @@ -23,6 +23,7 @@ *********************/ #define LV_BTN_INK_VALUE_MAX 256 #define LV_BTN_INK_VALUE_MAX_SHIFT 8 + /********************** * TYPEDEFS **********************/ @@ -209,7 +210,7 @@ void lv_btn_toggle(lv_obj_t * btn) } /** - * Set a function to call when the button event happens + * Set a function to call when a button event happens * @param btn pointer to a button object * @param action type of event form 'lv_action_t' (press, release, long press, long press repeat) */ diff --git a/lv_objx/lv_btn.h b/lv_objx/lv_btn.h index d48a501337..a726d23e00 100644 --- a/lv_objx/lv_btn.h +++ b/lv_objx/lv_btn.h @@ -37,7 +37,8 @@ extern "C" { * TYPEDEFS **********************/ -/*Button states*/ +/* Button states + * It can be used not only by buttons but other button-like objects too*/ typedef enum { LV_BTN_STATE_REL, @@ -120,7 +121,7 @@ void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state); void lv_btn_toggle(lv_obj_t * btn); /** - * Set a function to call when the button event happens + * Set a function to call when a button event happens * @param btn pointer to a button object * @param action type of event form 'lv_action_t' (press, release, long press, long press repeat) */ diff --git a/lv_objx/lv_img.c b/lv_objx/lv_img.c index 9b8594efc3..bc6cbba7aa 100644 --- a/lv_objx/lv_img.c +++ b/lv_objx/lv_img.c @@ -124,12 +124,6 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img) lv_img_src_t src_type = lv_img_src_get_type(src_img); lv_img_ext_t * ext = lv_obj_get_ext_attr(img); - -#if USE_LV_FILESYSTEM == 0 - if(src_type == LV_IMG_SRC_FILE) src_type = LV_IMG_SRC_UNKNOWN; -#endif - - /*If the new source type is unknown free the memories of the old source*/ if(src_type == LV_IMG_SRC_UNKNOWN) { if(ext->src_type == LV_IMG_SRC_SYMBOL || ext->src_type == LV_IMG_SRC_FILE) { @@ -260,7 +254,7 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode bool cover = false; if(ext->src_type == LV_IMG_SRC_UNKNOWN || ext->src_type == LV_IMG_SRC_SYMBOL) return false; - if(ext->cf == LV_IMG_FORMAT_TRUE_COLOR) cover = lv_area_is_in(mask, &img->coords); + if(ext->cf == LV_IMG_FORMAT_TRUE_COLOR || ext->cf == LV_IMG_FORMAT_RAW) cover = lv_area_is_in(mask, &img->coords); return cover; } else if(mode == LV_DESIGN_DRAW_MAIN) { diff --git a/lv_objx/lv_imgbtn.c b/lv_objx/lv_imgbtn.c new file mode 100644 index 0000000000..dae4b9e7c0 --- /dev/null +++ b/lv_objx/lv_imgbtn.c @@ -0,0 +1,255 @@ +/** + * @file lv_imgbtn.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_imgbtn.h" +#if USE_LV_IMGBTN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param); +static void refr_img(lv_obj_t * imgbtn); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_signal_func_t ancestor_signal; +static lv_design_func_t ancestor_design; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Create a image button object + * @param par pointer to an object, it will be the parent of the new image button + * @param copy pointer to a image button object, if not NULL then the new object will be copied from it + * @return pointer to the created image button + */ +lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy) +{ + LV_LOG_TRACE("image button create started"); + + /*Create the ancestor of image button*/ + lv_obj_t * new_imgbtn = lv_btn_create(par, copy); + lv_mem_assert(new_imgbtn); + if(new_imgbtn == NULL) return NULL; + + /*Allocate the image button type specific extended data*/ + lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(new_imgbtn, sizeof(lv_imgbtn_ext_t)); + lv_mem_assert(ext); + if(ext == NULL) return NULL; + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_imgbtn); + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_imgbtn); + + /*Initialize the allocated 'ext' */ + ext->img_src[LV_BTN_STATE_REL] = NULL; + ext->img_src[LV_BTN_STATE_PR] = NULL; + ext->img_src[LV_BTN_STATE_TGL_REL] = NULL; + ext->img_src[LV_BTN_STATE_TGL_PR] = NULL;; + ext->img_src[LV_BTN_STATE_INA] = NULL; + ext->act_cf = LV_IMG_FORMAT_UNKOWN; + + /*The signal and design functions are not copied so set them here*/ + lv_obj_set_signal_func(new_imgbtn, lv_imgbtn_signal); + lv_obj_set_design_func(new_imgbtn, lv_imgbtn_design); + + /*Init the new image button image button*/ + if(copy == NULL) { + + } + /*Copy an existing image button*/ + else { + lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + + /*Refresh the style with new signal function*/ + lv_obj_refresh_style(new_imgbtn); + } + + LV_LOG_INFO("image button created"); + + return new_imgbtn; +} + +/*===================== + * Setter functions + *====================*/ + +/** + * Set images for a state of the image button + * @param imgbtn pointer to an image button object + * @param state for which state set the new image (from `lv_btn_state_t`) ` + * @param src pointer to an image source (a C array or path to a file) + */ +void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, void * src) +{ + lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); + + ext->img_src[state] = src; + + refr_img(imgbtn); +} + +/** + * Set a style of a image button. + * @param imgbtn pointer to image button object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t * style) +{ + lv_btn_set_style(imgbtn, type, style); +} + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the images in a given state + * @param imgbtn pointer to an image button object + * @param state the state where to get the image (from `lv_btn_state_t`) ` + * @return pointer to an image source (a C array or path to a file) + */ +void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state) +{ + lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); + + return ext->img_src[state]; +} + +/** + * Get style of a image button. + * @param imgbtn pointer to image button object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type) +{ + return lv_btn_get_style(imgbtn, type); +} + +/*===================== + * Other functions + *====================*/ + +/* + * New object specific "other" functions come here + */ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Handle the drawing related tasks of the image buttons + * @param imgbtn 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_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); + bool cover = false; + if(ext->act_cf == LV_IMG_FORMAT_TRUE_COLOR || ext->act_cf == LV_IMG_FORMAT_RAW) { + cover = lv_area_is_in(mask, &imgbtn->coords); + } + + return cover; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + /*Just draw an image*/ + lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); + lv_btn_state_t state = lv_imgbtn_get_state(imgbtn); + void * src = ext->img_src[state]; + lv_style_t * style = lv_imgbtn_get_style(imgbtn, state); + lv_opa_t opa_scale = lv_obj_get_opa_scale(imgbtn); + lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale); + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + + } + + return true; +} + +/** + * Signal function of the image button + * @param imgbtn pointer to a image button object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param) +{ + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(imgbtn, sign, param); + if(res != LV_RES_OK) return res; + + if(sign == LV_SIGNAL_STYLE_CHG) { + /* If the style changed then the button was clicked, released etc. so probably the state was changed as well + * Set the new image for the new state.*/ + refr_img(imgbtn); + } + else if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_GET_TYPE) { + lv_obj_type_t * buf = param; + uint8_t i; + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + if(buf->type[i] == NULL) break; + } + buf->type[i] = "lv_imgbtn"; + } + + return res; +} + + +static void refr_img(lv_obj_t * imgbtn) +{ + lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); + lv_btn_state_t state = lv_imgbtn_get_state(imgbtn); + lv_img_header_t header; + void * src = ext->img_src[state]; + + lv_res_t info_res; + info_res = lv_img_dsc_get_info(src, &header); + if(info_res == LV_RES_OK) { + ext->act_cf = header.cf; + lv_obj_set_size(imgbtn, header.w, header.h); + } else { + ext->act_cf = LV_IMG_FORMAT_UNKOWN; + } + +} + +#endif diff --git a/lv_objx/lv_imgbtn.h b/lv_objx/lv_imgbtn.h new file mode 100644 index 0000000000..e3f935a28c --- /dev/null +++ b/lv_objx/lv_imgbtn.h @@ -0,0 +1,199 @@ +/** + * @file lv_imgbtn.h + * + */ + +#ifndef LV_IMGBTN_H +#define LV_IMGBTN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#ifdef LV_CONF_INCLUDE_SIMPLE +#include "lv_conf.h" +#else +#include "../../lv_conf.h" +#endif + +#if USE_LV_IMGBTN != 0 + +/*Testing of dependencies*/ +#if USE_LV_BTN == 0 +#error "lv_imgbtn: lv_btn is required. Enable it in lv_conf.h (USE_LV_BTN 1) " +#endif + +#include "../lv_core/lv_obj.h" +#include "lv_btn.h" +#include "../lv_draw/lv_draw_img.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +/*Data of image button*/ +typedef struct { + lv_btn_ext_t btn; /*Ext. of ancestor*/ + /*New data for this type */ + void * img_src[LV_BTN_STATE_NUM]; /*Store images to each state*/ + lv_img_color_format_t act_cf; /*Color format of the currently active image*/ +} lv_imgbtn_ext_t; + + +/*Styles*/ +typedef enum { + LV_IMGBTN_STYLE_REL, + LV_IMGBTN_STYLE_PR, + LV_IMGBTN_STYLE_TGL_REL, + LV_IMGBTN_STYLE_TGL_PR, + LV_IMGBTN_STYLE_INA, +} lv_imgbtn_style_t; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a image button objects + * @param par pointer to an object, it will be the parent of the new image button + * @param copy pointer to a image button object, if not NULL then the new object will be copied from it + * @return pointer to the created image button + */ +lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy); + +/*====================== + * Add/remove functions + *=====================*/ + + +/*===================== + * Setter functions + *====================*/ + +/** + * Set images for a state of the image button + * @param imgbtn pointer to an image button object + * @param state for which state set the new image (from `lv_btn_state_t`) ` + * @param src pointer to an image source (a C array or path to a file) + */ +void lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, void * src); + +/** + * Enable the toggled states. On release the button will change from/to toggled state. + * @param imgbtn pointer to an image button object + * @param tgl true: enable toggled states, false: disable + */ +static inline void lv_imgbtn_set_toggle(lv_obj_t * imgbtn, bool tgl) +{ + lv_btn_set_toggle(imgbtn, tgl); +} + +/** + * Set the state of the image button + * @param imgbtn pointer to an image button object + * @param state the new state of the button (from lv_btn_state_t enum) + */ +static inline void lv_imgbtn_set_state(lv_obj_t * imgbtn, lv_btn_state_t state) +{ + lv_btn_set_state(imgbtn, state); +} + +/** + * Toggle the state of the image button (ON->OFF, OFF->ON) + * @param imgbtn pointer to a image button object + */ +static inline void lv_imgbtn_toggle(lv_obj_t * imgbtn) +{ + lv_btn_toggle(imgbtn); +} + +/** + * Set a function to call when a button event happens + * @param imgbtn pointer to an image button object + * @param action type of event form 'lv_action_t' (press, release, long press, long press repeat) + */ +static inline void lv_imgbtn_set_action(lv_obj_t * imgbtn, lv_btn_action_t type, lv_action_t action) +{ + lv_btn_set_action(imgbtn, type, action); +} + +/** + * Set a style of a image button. + * @param imgbtn pointer to image button object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t *style); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the images in a given state + * @param imgbtn pointer to an image button object + * @param state the state where to get the image (from `lv_btn_state_t`) ` + * @return pointer to an image source (a C array or path to a file) + */ +void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state); + +/** + * Get the current state of the image button + * @param imgbtn pointer to a image button object + * @return the state of the button (from lv_btn_state_t enum) + */ +static inline lv_btn_state_t lv_imgbtn_get_state(const lv_obj_t * imgbtn) +{ + return lv_btn_get_state(imgbtn); +} + +/** + * Get the toggle enable attribute of the image button + * @param imgbtn pointer to a image button object + * @return ture: toggle enabled, false: disabled + */ +static inline bool lv_imgbtn_get_toggle(const lv_obj_t * imgbtn) +{ + return lv_btn_get_toggle(imgbtn); +} + +/** + * Get the release action of a image button + * @param imgbtn pointer to a image button object + * @return pointer to the release action function + */ +static inline lv_action_t lv_imgbtn_get_action(const lv_obj_t * imgbtn, lv_btn_action_t type) +{ + return lv_btn_get_action(imgbtn, type); +} + +/** + * Get style of a image button. + * @param imgbtn pointer to image button object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*USE_LV_IMGBTN*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_IMGBTN_H*/ diff --git a/lv_objx/lv_objx_templ.c b/lv_objx/lv_objx_templ.c index 8947ad66fe..b5c051009f 100644 --- a/lv_objx/lv_objx_templ.c +++ b/lv_objx/lv_objx_templ.c @@ -16,7 +16,6 @@ //#include "lv_templ.h" /*TODO uncomment this*/ #if USE_LV_TEMPL != 0 - /********************* * DEFINES *********************/ @@ -59,10 +58,12 @@ lv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy) /*TODO modify it to the ancestor create function */ lv_obj_t * new_templ = lv_ANCESTOR_create(par, copy); lv_mem_assert(new_templ); + if(new_templ == NULL) return NULL; /*Allocate the template type specific extended data*/ lv_templ_ext_t * ext = lv_obj_allocate_ext_attr(new_templ, sizeof(lv_templ_ext_t)); lv_mem_assert(ext); + if(ext == NULL) return NULL; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_templ); if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_templ); @@ -87,7 +88,6 @@ lv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy) LV_LOG_INFO("template created"); - return new_templ; } @@ -114,7 +114,7 @@ lv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy) * @param templ pointer to template object * @param type which style should be set * @param style pointer to a style - * */ + */ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t * style) { lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ); @@ -140,7 +140,7 @@ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t * st * @param templ pointer to template object * @param type which style should be get * @return style pointer to the style - * */ + */ lv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type) { lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ); diff --git a/lv_objx/lv_objx_templ.h b/lv_objx/lv_objx_templ.h index afe20b90b8..17dab72f85 100644 --- a/lv_objx/lv_objx_templ.h +++ b/lv_objx/lv_objx_templ.h @@ -78,7 +78,7 @@ lv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy); * @param templ pointer to template object * @param type which style should be set * @param style pointer to a style - * */ + */ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t *style); /*===================== @@ -90,7 +90,7 @@ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t *sty * @param templ pointer to template object * @param type which style should be get * @return style pointer to the style - * */ + */ lv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type); /*===================== diff --git a/lvgl.h b/lvgl.h index ceee7358b5..80538b6c64 100644 --- a/lvgl.h +++ b/lvgl.h @@ -27,7 +27,7 @@ extern "C" { #include "lv_themes/lv_theme.h" #include "lv_objx/lv_btn.h" -#include "lv_objx/lv_img.h" +#include "lv_objx/lv_imgbtn.h" #include "lv_objx/lv_img.h" #include "lv_objx/lv_label.h" #include "lv_objx/lv_line.h"