Beispiel #1
0
/**
 * Signal function of the roller
 * @param roller pointer to a roller 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_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param)
{
    lv_res_t res  = LV_RES_OK;

    /*Don't let the drop down list to handle the control signals. It works differently*/
    if(sign != LV_SIGNAL_CONTROLL && sign != LV_SIGNAL_FOCUS && sign != LV_SIGNAL_DEFOCUS) {
         /* Include the ancient signal function */
        res = ancestor_signal(roller, sign, param);
        if(res != LV_RES_OK) return res;
    }

    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
    if(sign == LV_SIGNAL_STYLE_CHG) {
        lv_obj_set_height(lv_page_get_scrl(roller),
                             lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller));
        lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0);
        lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);
        refr_position(roller, false);
    } else if(sign == LV_SIGNAL_CORD_CHG) {

        if(lv_obj_get_width(roller) != lv_area_get_width(param) ||
           lv_obj_get_height(roller) != lv_area_get_height(param)) {

            lv_ddlist_set_fix_height(roller, lv_obj_get_height(roller));
            lv_obj_set_height(lv_page_get_scrl(roller),
                                 lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller));

            lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0);
            lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);
            refr_position(roller, false);
        }
    } else if(sign == LV_SIGNAL_CONTROLL) {
        char c = *((char*)param);
        if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
            if(ext->ddlist.sel_opt_id +1 < ext->ddlist.option_cnt) {

                lv_roller_set_selected(roller, ext->ddlist.sel_opt_id + 1, true);
                if(ext->ddlist.action != NULL) {
                    ext->ddlist.action(roller);
                }
            }
        } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
            if(ext->ddlist.sel_opt_id > 0) {
                lv_roller_set_selected(roller, ext->ddlist.sel_opt_id - 1, true);
                if(ext->ddlist.action != NULL) {
                    ext->ddlist.action(roller);
                }
            }
        }
    }

    return res;
}
Beispiel #2
0
/**
 * Create a roller object
 * @param par pointer to an object, it will be the parent of the new roller
 * @param copy pointer to a roller object, if not NULL then the new object will be copied from it
 * @return pointer to the created roller
 */
lv_obj_t * lv_roller_create(lv_obj_t * par, lv_obj_t * copy)
{
    /*Create the ancestor of roller*/
	lv_obj_t * new_roller = lv_ddlist_create(par, copy);
    lv_mem_assert(new_roller);
    if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(new_roller));
    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_roller);
    
    /*Allocate the roller type specific extended data*/
    lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(new_roller, sizeof(lv_roller_ext_t));
    lv_mem_assert(ext);

    /*The signal and design functions are not copied so set them here*/
    lv_obj_set_signal_func(new_roller, lv_roller_signal);
    lv_obj_set_design_func(new_roller, lv_roller_design);

    /*Init the new roller roller*/
    if(copy == NULL) {
        lv_obj_t * scrl = lv_page_get_scrl(new_roller);
        lv_obj_set_drag(scrl, true);                        /*In ddlist is might be disabled*/
        lv_page_set_rel_action(new_roller, NULL);       /*Roller don't uses it (like ddlist)*/
        lv_page_set_scrl_fit(new_roller, true, false);      /*Height is specified directly*/
        lv_ddlist_open(new_roller, false);
        lv_ddlist_set_anim_time(new_roller, LV_ROLLER_ANIM_TIME);
        lv_roller_set_visible_row_count(new_roller, 3);
        lv_label_set_align(ext->ddlist.label, LV_LABEL_ALIGN_CENTER);

        lv_obj_set_signal_func(scrl, lv_roller_scrl_signal);

        /*Set the default styles*/
        lv_theme_t *th = lv_theme_get_current();
        if(th) {
            lv_roller_set_style(new_roller, LV_ROLLER_STYLE_BG, th->roller.bg);
            lv_roller_set_style(new_roller, LV_ROLLER_STYLE_SEL, th->roller.sel);
        } else {
            /*Let the ddlist's style*/
            lv_obj_refresh_style(new_roller);                /*To set scrollable size automatically*/
        }
    }
    /*Copy an existing roller*/
    else {
        lv_obj_t * scrl = lv_page_get_scrl(new_roller);
        lv_ddlist_open(new_roller, false);
        lv_obj_set_signal_func(scrl, lv_roller_scrl_signal);

        lv_obj_refresh_style(new_roller);        /*Refresh the style with new signal function*/
    }
    
    return new_roller;
}
Beispiel #3
0
/**
 * Refresh the position of the roller. It uses the id stored in: ext->ddlist.selected_option_id
 * @param roller pointer to a roller object
 * @param anim_en true: refresh with animation; false: without animation
 */
static void refr_position(lv_obj_t *roller, bool anim_en)
{
    lv_obj_t *roller_scrl = lv_page_get_scrl(roller);
    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
    lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);
    const lv_font_t * font = style_label->text.font;
    lv_coord_t font_h = lv_font_get_height_scale(font);
    lv_coord_t h = lv_obj_get_height(roller);
    int32_t id = ext->ddlist.sel_opt_id;
    lv_coord_t line_y1 = id * (font_h + style_label->text.line_space) + ext->ddlist.label->coords.y1 - roller_scrl->coords.y1;
    lv_coord_t new_y = - line_y1 + (h - font_h) / 2;

    if(ext->ddlist.anim_time == 0 || anim_en == false) {
        lv_obj_set_y(roller_scrl, new_y);
    } else {
#if USE_LV_ANIMATION
        lv_anim_t a;
        a.var = roller_scrl;
        a.start = lv_obj_get_y(roller_scrl);
        a.end = new_y;
        a.fp = (lv_anim_fp_t)lv_obj_set_y;
        a.path = lv_anim_path_linear;
        a.end_cb = NULL;
        a.act_time = 0;
        a.time = ext->ddlist.anim_time;
        a.playback = 0;
        a.playback_pause = 0;
        a.repeat = 0;
        a.repeat_pause = 0;
        lv_anim_create(&a);
#endif
    }
}
Beispiel #4
0
/**
 * Close (Collapse) the drop down list
 * @param ddlist pointer to drop down list object
 * @param anim_en true: use animation; false: not use animations
 */
void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en)
{
#if USE_LV_ANIMATION == 0
    anim_en = false;
#endif
    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
    ext->opened = 0;
    lv_obj_set_drag(lv_page_get_scrl(ddlist), false);
    lv_ddlist_refr_size(ddlist, anim_en);
}
Beispiel #5
0
/**
 * Create an mpty list on the window. 'win_load_file_list' will fill it.
 * @param app pointer to a Files application
 */
static void win_create_list(lv_app_inst_t * app)
{
    my_win_data_t * win_data = app->win_data;

    /*Delete the previous list*/
    if(win_data->file_list != NULL) {
      lv_obj_del(win_data->file_list);
    }

    /*Create a new list*/
    win_data->file_list = lv_list_create(app->win, NULL);
    lv_obj_set_width(win_data->file_list, lv_win_get_width(app->win));
    lv_list_set_style_img(win_data->file_list, &style_btn_symbol);
    lv_obj_set_style(lv_page_get_scrl(win_data->file_list), lv_style_get(LV_STYLE_TRANSP_TIGHT, NULL));
    lv_obj_set_drag_parent(win_data->file_list, true);
    lv_obj_set_drag_parent(lv_page_get_scrl(win_data->file_list), true);
    lv_cont_set_fit(win_data->file_list, false, true);
    lv_cont_set_layout(lv_page_get_scrl(win_data->file_list), LV_CONT_LAYOUT_COL_L);
}
Beispiel #6
0
/**
 * Called when a drop down list is released to open it or set new option
 * @param ddlist pointer to a drop down list object
 * @return LV_ACTION_RES_INV if the ddlist it deleted in the user callback else LV_ACTION_RES_OK
 */
static lv_res_t lv_ddlist_release_action(lv_obj_t * ddlist)
{
    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);

    if(ext->opened == 0) { /*Open the list*/
        ext->opened = 1;
        lv_obj_set_drag(lv_page_get_scrl(ddlist), true);
    } else {
        ext->opened = 0;
        lv_obj_set_drag(lv_page_get_scrl(ddlist), false);

        /*Search the clicked option*/
        lv_indev_t *indev = lv_indev_get_act();
        lv_point_t p;
        lv_indev_get_point(indev, &p);
        p.x -= ext->label->coords.x1;
        p.y -= ext->label->coords.y1;
        uint16_t letter_i;
        letter_i = lv_label_get_letter_on(ext->label, &p);

        uint16_t new_opt = 0;
        const char * txt = lv_label_get_text(ext->label);
        uint16_t i;
        for(i = 0; i < letter_i; i++) {
            if(txt[i] == '\n') new_opt ++;
        }

        ext->sel_opt_id = new_opt;

        if(ext->action != NULL) {
            ext->action(ddlist);
        }
    }
    lv_ddlist_refr_size(ddlist, true);

    return LV_RES_OK;

}
Beispiel #7
0
/**
 * Set the position of list when it is closed to show the selected item
 * @param ddlist pointer to a drop down list
 */
static void lv_ddlist_pos_current_option(lv_obj_t * ddlist)
{
    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
    lv_style_t * style = lv_obj_get_style(ddlist);
    const lv_font_t * font = style->text.font;
    lv_coord_t font_h = lv_font_get_height(font);
    lv_style_t * label_style = lv_obj_get_style(ext->label);
    lv_obj_t * scrl = lv_page_get_scrl(ddlist);

    lv_coord_t h = lv_obj_get_height(ddlist);
    lv_coord_t line_y1 = ext->sel_opt_id * (font_h + label_style->text.line_space) + ext->label->coords.y1 - scrl->coords.y1;

    lv_obj_set_y(scrl, - line_y1 + (h - font_h) / 2);

}
Beispiel #8
0
/**
 * Set a style of a drop down list
 * @param ddlist pointer to a drop down list object
 * @param type which style should be set
 * @param style pointer to a style
 */
void lv_ddlist_set_style(lv_obj_t *ddlist, lv_ddlist_style_t type, lv_style_t *style)
{
    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);

    switch (type) {
        case LV_DDLIST_STYLE_BG:
            lv_page_set_style(ddlist, LV_PAGE_STYLE_BG, style);
            break;
        case LV_DDLIST_STYLE_SB:
            lv_page_set_style(ddlist, LV_PAGE_STYLE_SB, style);
            break;
        case LV_DDLIST_STYLE_SEL:
            ext->sel_style = style;
            lv_obj_t *scrl = lv_page_get_scrl(ddlist);
            lv_obj_refresh_ext_size(scrl);  /*Because of the wider selected rectangle*/
            break;
    }
}
Beispiel #9
0
/**
 * Refresh the size of drop down list according to its status (open or closed)
 * @param ddlist pointer to a drop down list object
 * @param anim_en Change the size (open/close) with or without animation (true/false)
 */
static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
{
#if USE_LV_ANIMATION == 0
    anim_en = false;
#endif
    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
    lv_style_t * style = lv_obj_get_style(ddlist);
    lv_coord_t new_height;
    if(ext->opened) { /*Open the list*/
        if(ext->fix_height == 0) new_height = lv_obj_get_height(lv_page_get_scrl(ddlist)) + 2 * style->body.padding.ver;
        else new_height = ext->fix_height;
    } else { /*Close the list*/
        const lv_font_t * font = style->text.font;
        lv_style_t * label_style = lv_obj_get_style(ext->label);
        lv_coord_t font_h = lv_font_get_height(font);
        new_height = font_h + 2 * label_style->text.line_space;
    }

    if(anim_en == 0) {
        lv_obj_set_height(ddlist, new_height);
        lv_ddlist_pos_current_option(ddlist);
    } else {
#if USE_LV_ANIMATION
        lv_anim_t a;
        a.var = ddlist;
        a.start = lv_obj_get_height(ddlist);
        a.end = new_height;
        a.fp = (lv_anim_fp_t)lv_obj_set_height;
        a.path = lv_anim_path_linear;
        a.end_cb = (lv_anim_cb_t)lv_ddlist_pos_current_option;
        a.act_time = 0;
        a.time = ext->anim_time;
        a.playback = 0;
        a.playback_pause = 0;
        a.repeat = 0;
        a.repeat_pause = 0;

        lv_anim_create(&a);
#endif
    }
}
Beispiel #10
0
/**
 * 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);
    lv_mem_assert(new_ddlist);
    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_ddlist);
    if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_func(lv_page_get_scrl(new_ddlist));
    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_ddlist);
    
    /*Allocate the drop down list type specific extended data*/
    lv_ddlist_ext_t * ext = lv_obj_allocate_ext_attr(new_ddlist, sizeof(lv_ddlist_ext_t));
    lv_mem_assert(ext);

    /*Initialize the allocated 'ext' */
    ext->label = NULL;
    ext->action = NULL;
    ext->opened = 0;
    ext->fix_height = 0;
    ext->sel_opt_id = 0;
    ext->sel_opt_id_ori = 0;
    ext->option_cnt = 0;
    ext->anim_time = LV_DDLIST_ANIM_TIME;
    ext->sel_style = &lv_style_plain_color;

    /*The signal and design functions are not copied so set them here*/
    lv_obj_set_signal_func(new_ddlist, lv_ddlist_signal);
    lv_obj_set_signal_func(lv_page_get_scrl(new_ddlist), lv_ddlist_scrl_signal);
    lv_obj_set_design_func(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_page_set_scrl_fit(new_ddlist, true, true);

        ext->label = lv_label_create(new_ddlist, NULL);
        lv_cont_set_fit(new_ddlist, true, false);
        lv_page_set_rel_action(new_ddlist, lv_ddlist_release_action);
        lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_DRAG);
        lv_page_set_style(new_ddlist, LV_PAGE_STYLE_SCRL, &lv_style_transp_tight);

        lv_ddlist_set_options(new_ddlist, "Option 1\nOption 2\nOption 3");

        /*Set the default styles*/
        lv_theme_t *th = lv_theme_get_current();
        if(th) {
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_BG, th->ddlist.bg);
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL,th->ddlist.sel);
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, th->ddlist.sb);
        } else {
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_BG, &lv_style_pretty);
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL, &lv_style_plain_color);
            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, &lv_style_pretty_color);
        }
    }
    /*Copy an existing drop down list*/
    else {
    	lv_ddlist_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
        ext->label = lv_label_create(new_ddlist, copy_ext->label);
        lv_label_set_text(ext->label, lv_label_get_text(copy_ext->label));
        ext->sel_opt_id = copy_ext->sel_opt_id;
        ext->fix_height = copy_ext->fix_height;
        ext->action = copy_ext->action;
        ext->option_cnt = copy_ext->option_cnt;
        ext->sel_style = copy_ext->sel_style;
        ext->anim_time = copy_ext->anim_time;

        /*Refresh the style with new signal function*/
        lv_obj_refresh_style(new_ddlist);
    }
    
    return new_ddlist;
}
Beispiel #11
0
/**
 * Load the file list from the current path on the window
 * @param app pointer to a Files application
 */
static void win_load_file_list(lv_app_inst_t * app)
{
    my_app_data_t * app_data = app->app_data;
    my_win_data_t * win_data = app->win_data;

    /*Create a new list*/
    win_create_list(app);

    fs_res_t res = FS_RES_OK;

      /*At empty path show the drivers */
    lv_obj_t * liste;
    if(app_data->path[0] == '\0') {
        char drv[16];
        char buf[2];
        fs_get_letters(drv);
        uint8_t i;
        for(i = 0; drv[i] != '\0'; i++) {
            buf[0] = drv[i];
            buf[1] = '\0';
            liste = lv_list_add(win_data->file_list, SYMBOL_DRIVE, buf, win_drv_action);
            lv_obj_set_free_p(liste, app);
        }
    }
    /*List the files/folders with fs interface*/
    else {
        liste = lv_list_add(win_data->file_list, SYMBOL_UP, "Up", win_up_action);
        lv_obj_set_free_p(liste, app);

        fs_readdir_t rd;
        res = fs_readdir_init(&rd, app_data->path);
        if(res != FS_RES_OK) {
            lv_app_notice_add("Can not read the\npath in Files");
        return;
        }

        /*At not first page add prev. page button */
        if(app_data->file_cnt != 0) {
            liste = lv_list_add(win_data->file_list, SYMBOL_LEFT, "Previous page", win_prev_action);
            lv_obj_set_free_p(liste, app);
        }

        char fn[LV_APP_FILES_FN_MAX_LEN];

        /*Read the files from the previous pages*/
        uint16_t file_cnt = 0;
        while(file_cnt <= app_data->file_cnt) {
            res = fs_readdir(&rd, fn);
            if(res != FS_RES_OK ){
                lv_app_notice_add("Can not read\nthe path in Files");
                return;
            }
            file_cnt ++;
        }

        /*Add list elements from the files and folders*/
        while(res == FS_RES_OK && fn[0] != '\0') {
            if(fn[0] == '/') { /*Add a folder*/
                lv_obj_t * liste;
                liste = lv_list_add(win_data->file_list, SYMBOL_FOLDER, &fn[1], win_folder_action);
                lv_obj_set_free_p(liste, app);
                app_data->file_cnt ++;
            }
            /*Add a file*/
            else {
                liste = lv_list_add(win_data->file_list, SYMBOL_FILE, fn, win_file_action);
                lv_obj_set_free_p(liste, app);
                app_data->file_cnt ++;
            }

            /*Get the next element*/
            res = fs_readdir(&rd, fn);

            /*Show only LV_APP_FSEL_MAX_FILE elements and add a Next page button*/
            if(app_data->file_cnt != 0 && app_data->file_cnt % LV_APP_FILES_PAGE_SIZE == 0) {
                liste = lv_list_add(win_data->file_list, SYMBOL_RIGHT, "Next page", win_next_action);
                lv_obj_set_free_p(liste, app);
                break;
            }
        }

      /*Close the read directory*/
      fs_readdir_close(&rd);
    }

    if(res != FS_RES_OK) {
        lv_app_notice_add("Can not read\nthe path in Files");
    }

    /*Focus to the top of the list*/
    lv_obj_set_y(lv_page_get_scrl(win_data->file_list), 0);
    return;
}