<commit_before>/**
 * @file lv_ddlist.c
 * 
 */


/*********************
 *      INCLUDES
 *********************/
#include "lv_conf.h"
#if USE_LV_DDLIST != 0

#include "lv_ddlist.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/anim.h"
#include "../lv_obj/lv_group.h"

/*********************
 *      DEFINES
 *********************/
#define LV_DDLIST_DEF_ANIM_TIME 200 /*ms*/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_mode_t mode);
static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * dispi);
static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time);
static void lv_ddlist_pos_act_option(lv_obj_t * ddlist);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_design_f_t  ancestor_design_f;
static const char * def_options[] = {"Option 1", "Option 2", "Option 3", ""};
/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/*----------------- 
 * Create function
 *-----------------*/

/**
 * Create a drop down list objects
 * @param par pointer to an object, it will be the parent of the new drop down list
 * @param copy pointer to a drop down list object, if not NULL then the new object will be copied from it
 * @return pointer to the created drop down list
 */
lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
{
    /*Create the ancestor drop down list*/
    lv_obj_t * new_ddlist = lv_page_create(par, copy);
    dm_assert(new_ddlist);
    
    /*Allocate the drop down list type specific extended data*/
    lv_ddlist_ext_t * ext = lv_obj_alloc_ext(new_ddlist, sizeof(lv_ddlist_ext_t));
    dm_assert(ext);

    /*Initialize the allocated 'ext' */
    ext->opt_label = NULL;
    ext->cb = NULL;
    ext->opened = 0;
    ext->auto_size = 0;
    ext->sel_opt = 0;
    ext->num_opt = 0;
    ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
    ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);

    /*The signal and design functions are not copied so set them here*/
    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_ddlist);

    lv_obj_set_signal_f(new_ddlist, lv_ddlist_signal);
    lv_obj_set_design_f(new_ddlist, lv_ddlist_design);

    /*Init the new drop down list drop down list*/
    if(copy == NULL) {
        lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
        lv_obj_set_drag(scrl, false);
        lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
        lv_cont_set_fit(scrl, true, true);

        ext->opt_label = lv_label_create(new_ddlist, NULL);
        lv_cont_set_fit(new_ddlist, true, false);
        lv_page_set_rel_action(new_ddlist, lv_ddlist_rel_action);
        lv_page_set_sb_mode(new_ddlist, LV_PAGE_SB_MODE_DRAG);
        lv_obj_set_style(new_ddlist, lv_style_get(LV_STYLE_PRETTY, NULL));
        lv_ddlist_set_options(new_ddlist, def_options);
    }
    /*Copy an existing drop down list*/
    else {
    	lv_ddlist_ext_t * copy_ext = lv_obj_get_ext(copy);
        ext->opt_label = lv_label_create(new_ddlist, copy_ext->opt_label);
        lv_label_set_text(ext->opt_label, lv_label_get_text(copy_ext->opt_label));
        ext->sel_opt = copy_ext->sel_opt;
        ext->auto_size = copy_ext->auto_size;
        ext->cb = copy_ext->cb;

        /*Refresh the style with new signal function*/
        lv_obj_refr_style(new_ddlist);
    }
    
    return new_ddlist;
}

/**
 * Signal function of the drop down list
 * @param ddlist pointer to a drop down list 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_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
{
    bool valid;

    /* Include the ancient signal function */
    valid = lv_page_signal(ddlist, sign, param);

    /* The object can be deleted so check its validity and then
     * make the object specific signal handling */
    if(valid != false) {
    	if(sign == LV_SIGNAL_STYLE_CHG) {
    	    lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
    	    lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
            lv_ddlist_refr_size(ddlist, 0);
    	} else if(sign == LV_SIGNAL_FOCUS) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
    	    if(ext->opened == false) {
    	        ext->opened = true;
    	        lv_ddlist_refr_size(ddlist, true);
    	    }
    	} else if(sign == LV_SIGNAL_DEFOCUS) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
            if(ext->opened != false) {
                ext->opened = false;
                lv_ddlist_refr_size(ddlist, true);
            }
        } else if(sign == LV_SIGNAL_CONTROLL) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
            char c = *((char*)param);
            if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
                if(ext->sel_opt < ext->num_opt - 1) {
                    ext->sel_opt ++;
                    lv_obj_inv(ddlist);
                    if(ext->cb != NULL) {
                        ext->cb(ddlist, NULL);
                    }
                }
            } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
                if(ext->sel_opt > 0) {
                    ext->sel_opt --;<commit_msg>lv_obj: lv_ddlist: bugfix, copy 'num_opt' attribute too<commit_after>/**
 * @file lv_ddlist.c
 * 
 */


/*********************
 *      INCLUDES
 *********************/
#include "lv_conf.h"
#if USE_LV_DDLIST != 0

#include "lv_ddlist.h"
#include "../lv_draw/lv_draw.h"
#include "misc/gfx/anim.h"
#include "../lv_obj/lv_group.h"

/*********************
 *      DEFINES
 *********************/
#define LV_DDLIST_DEF_ANIM_TIME 200 /*ms*/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_mode_t mode);
static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * dispi);
static void lv_ddlist_refr_size(lv_obj_t * ddlist, uint16_t anim_time);
static void lv_ddlist_pos_act_option(lv_obj_t * ddlist);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_design_f_t  ancestor_design_f;
static const char * def_options[] = {"Option 1", "Option 2", "Option 3", ""};
/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/*----------------- 
 * Create function
 *-----------------*/

/**
 * Create a drop down list objects
 * @param par pointer to an object, it will be the parent of the new drop down list
 * @param copy pointer to a drop down list object, if not NULL then the new object will be copied from it
 * @return pointer to the created drop down list
 */
lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
{
    /*Create the ancestor drop down list*/
    lv_obj_t * new_ddlist = lv_page_create(par, copy);
    dm_assert(new_ddlist);
    
    /*Allocate the drop down list type specific extended data*/
    lv_ddlist_ext_t * ext = lv_obj_alloc_ext(new_ddlist, sizeof(lv_ddlist_ext_t));
    dm_assert(ext);

    /*Initialize the allocated 'ext' */
    ext->opt_label = NULL;
    ext->cb = NULL;
    ext->opened = 0;
    ext->auto_size = 0;
    ext->sel_opt = 0;
    ext->num_opt = 0;
    ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
    ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);

    /*The signal and design functions are not copied so set them here*/
    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_ddlist);

    lv_obj_set_signal_f(new_ddlist, lv_ddlist_signal);
    lv_obj_set_design_f(new_ddlist, lv_ddlist_design);

    /*Init the new drop down list drop down list*/
    if(copy == NULL) {
        lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
        lv_obj_set_drag(scrl, false);
        lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
        lv_cont_set_fit(scrl, true, true);

        ext->opt_label = lv_label_create(new_ddlist, NULL);
        lv_cont_set_fit(new_ddlist, true, false);
        lv_page_set_rel_action(new_ddlist, lv_ddlist_rel_action);
        lv_page_set_sb_mode(new_ddlist, LV_PAGE_SB_MODE_DRAG);
        lv_obj_set_style(new_ddlist, lv_style_get(LV_STYLE_PRETTY, NULL));
        lv_ddlist_set_options(new_ddlist, def_options);
    }
    /*Copy an existing drop down list*/
    else {
    	lv_ddlist_ext_t * copy_ext = lv_obj_get_ext(copy);
        ext->opt_label = lv_label_create(new_ddlist, copy_ext->opt_label);
        lv_label_set_text(ext->opt_label, lv_label_get_text(copy_ext->opt_label));
        ext->sel_opt = copy_ext->sel_opt;
        ext->auto_size = copy_ext->auto_size;
        ext->cb = copy_ext->cb;
        ext->num_opt = copy_ext->num_opt;

        /*Refresh the style with new signal function*/
        lv_obj_refr_style(new_ddlist);
    }
    
    return new_ddlist;
}

/**
 * Signal function of the drop down list
 * @param ddlist pointer to a drop down list 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_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
{
    bool valid;

    /* Include the ancient signal function */
    valid = lv_page_signal(ddlist, sign, param);

    /* The object can be deleted so check its validity and then
     * make the object specific signal handling */
    if(valid != false) {
    	if(sign == LV_SIGNAL_STYLE_CHG) {
    	    lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
    	    lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
            lv_ddlist_refr_size(ddlist, 0);
    	} else if(sign == LV_SIGNAL_FOCUS) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
    	    if(ext->opened == false) {
    	        ext->opened = true;
    	        lv_ddlist_refr_size(ddlist, true);
    	    }
    	} else if(sign == LV_SIGNAL_DEFOCUS) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
            if(ext->opened != false) {
                ext->opened = false;
                lv_ddlist_refr_size(ddlist, true);
            }
        } else if(sign == LV_SIGNAL_CONTROLL) {
            lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
            char c = *((char*)param);
            if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
                if(ext->sel_opt +1 < ext->num_opt) {
                    ext->sel_opt ++;
                    lv_obj_inv(ddlist);
                    if(ext->cb != NULL) {
                        ext->cb(ddlist, NULL);
                    }
                }
            } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
                if(ext->sel_opt > 0) {
                    ext->sel_opt --;
{'fraction_non_alphanumeric': 0.16067103256481566, 'fraction_numerical': 0.0028707275500134567, 'mean_word_length': 2.8789144050104385, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6395001', 'n_tokens_mistral': 4098, 'n_tokens_neox': 3909, 'n_words': 822}