diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a110f1b9..50e885d22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,9 @@ Available in the `dev` branch - Add `lv_chart_set_y_range()` to allow setting range of secondary y axis (based on `lv_chart_set_range` but extended with an axis parameter) - Allow setting different font for the selected text in `lv_roller` - Add `theme->apply_cb` to replace `theme->apply_xcb` to make it compatible with the MicroPython binding -- Add `lv_theme_set_base()` to allow easy extension of built-in (or any) themes. +- Add `lv_theme_set_base()` to allow easy extension of built-in (or any) themes - Add `lv_obj_align_x()` and `lv_obj_align_y()` functions +- Add `lv_obj_align_origo_x()` and `lv_obj_align_origo_y()` functions ## v7.1.0 (planned on 07.07.2020) *Available in the `master` branch* diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 55cef5424..481033d60 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -86,6 +86,7 @@ static void report_style_mod_core(void * style_p, lv_obj_t * obj); static void refresh_children_style(lv_obj_t * obj); static void base_dir_refr_children(lv_obj_t * obj); static void obj_align_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, lv_coord_t x_ofs, lv_coord_t y_ofs); +static void obj_align_origo_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, lv_coord_t x_ofs, lv_coord_t y_ofs); #if LV_USE_ANIMATION static lv_style_trans_t * trans_create(lv_obj_t * obj, lv_style_property_t prop, uint8_t part, lv_state_t prev_state, lv_state_t new_state); @@ -960,12 +961,6 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_coord_t new_x = lv_obj_get_x(obj); - lv_coord_t new_y = lv_obj_get_y(obj); - - lv_coord_t obj_w_half = lv_obj_get_width(obj) / 2; - lv_coord_t obj_h_half = lv_obj_get_height(obj) / 2; - if(base == NULL) { base = lv_obj_get_parent(obj); } @@ -973,123 +968,7 @@ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, LV_ASSERT_OBJ(base, LV_OBJX_NAME); - switch(align) { - case LV_ALIGN_CENTER: - new_x = lv_obj_get_width(base) / 2 - obj_w_half; - new_y = lv_obj_get_height(base) / 2 - obj_h_half; - break; - - case LV_ALIGN_IN_TOP_LEFT: - new_x = -obj_w_half; - new_y = -obj_h_half; - break; - case LV_ALIGN_IN_TOP_MID: - new_x = lv_obj_get_width(base) / 2 - obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_IN_TOP_RIGHT: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_IN_BOTTOM_LEFT: - new_x = -obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - case LV_ALIGN_IN_BOTTOM_MID: - new_x = lv_obj_get_width(base) / 2 - obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_IN_BOTTOM_RIGHT: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_IN_LEFT_MID: - new_x = -obj_w_half; - new_y = lv_obj_get_height(base) / 2 - obj_h_half; - break; - - case LV_ALIGN_IN_RIGHT_MID: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = lv_obj_get_height(base) / 2 - obj_h_half; - break; - - case LV_ALIGN_OUT_TOP_LEFT: - new_x = -obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_OUT_TOP_MID: - new_x = lv_obj_get_width(base) / 2 - obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_OUT_TOP_RIGHT: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_OUT_BOTTOM_LEFT: - new_x = -obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_OUT_BOTTOM_MID: - new_x = lv_obj_get_width(base) / 2 - obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_OUT_BOTTOM_RIGHT: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_OUT_LEFT_TOP: - new_x = -obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_OUT_LEFT_MID: - new_x = -obj_w_half; - new_y = lv_obj_get_height(base) / 2 - obj_h_half; - break; - - case LV_ALIGN_OUT_LEFT_BOTTOM: - new_x = -obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - - case LV_ALIGN_OUT_RIGHT_TOP: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = -obj_h_half; - break; - - case LV_ALIGN_OUT_RIGHT_MID: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = lv_obj_get_height(base) / 2 - obj_h_half; - break; - - case LV_ALIGN_OUT_RIGHT_BOTTOM: - new_x = lv_obj_get_width(base) - obj_w_half; - new_y = lv_obj_get_height(base) - obj_h_half; - break; - } - - /*Bring together the coordination system of base and obj*/ - lv_obj_t * par = lv_obj_get_parent(obj); - lv_coord_t base_abs_x = base->coords.x1; - lv_coord_t base_abs_y = base->coords.y1; - lv_coord_t par_abs_x = par->coords.x1; - lv_coord_t par_abs_y = par->coords.y1; - new_x += x_ofs + base_abs_x; - new_y += y_ofs + base_abs_y; - new_x -= par_abs_x; - new_y -= par_abs_y; - - lv_obj_set_pos(obj, new_x, new_y); + obj_align_core(obj, base, align, true, true, x_ofs, y_ofs); #if LV_USE_OBJ_REALIGN /*Save the last align parameters to use them in `lv_obj_realign`*/ @@ -3914,6 +3793,136 @@ static void obj_align_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t ali else if(y_set) lv_obj_set_y(obj, new_pos.y); } +static void obj_align_origo_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, lv_coord_t x_ofs, lv_coord_t y_ofs) +{ + lv_coord_t new_x = lv_obj_get_x(obj); + lv_coord_t new_y = lv_obj_get_y(obj); + + lv_coord_t obj_w_half = lv_obj_get_width(obj) / 2; + lv_coord_t obj_h_half = lv_obj_get_height(obj) / 2; + + + switch(align) { + case LV_ALIGN_CENTER: + new_x = lv_obj_get_width(base) / 2 - obj_w_half; + new_y = lv_obj_get_height(base) / 2 - obj_h_half; + break; + + case LV_ALIGN_IN_TOP_LEFT: + new_x = -obj_w_half; + new_y = -obj_h_half; + break; + case LV_ALIGN_IN_TOP_MID: + new_x = lv_obj_get_width(base) / 2 - obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_IN_TOP_RIGHT: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_IN_BOTTOM_LEFT: + new_x = -obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + case LV_ALIGN_IN_BOTTOM_MID: + new_x = lv_obj_get_width(base) / 2 - obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_IN_BOTTOM_RIGHT: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_IN_LEFT_MID: + new_x = -obj_w_half; + new_y = lv_obj_get_height(base) / 2 - obj_h_half; + break; + + case LV_ALIGN_IN_RIGHT_MID: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = lv_obj_get_height(base) / 2 - obj_h_half; + break; + + case LV_ALIGN_OUT_TOP_LEFT: + new_x = -obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_OUT_TOP_MID: + new_x = lv_obj_get_width(base) / 2 - obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_OUT_TOP_RIGHT: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_OUT_BOTTOM_LEFT: + new_x = -obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_OUT_BOTTOM_MID: + new_x = lv_obj_get_width(base) / 2 - obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_OUT_BOTTOM_RIGHT: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_OUT_LEFT_TOP: + new_x = -obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_OUT_LEFT_MID: + new_x = -obj_w_half; + new_y = lv_obj_get_height(base) / 2 - obj_h_half; + break; + + case LV_ALIGN_OUT_LEFT_BOTTOM: + new_x = -obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + + case LV_ALIGN_OUT_RIGHT_TOP: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = -obj_h_half; + break; + + case LV_ALIGN_OUT_RIGHT_MID: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = lv_obj_get_height(base) / 2 - obj_h_half; + break; + + case LV_ALIGN_OUT_RIGHT_BOTTOM: + new_x = lv_obj_get_width(base) - obj_w_half; + new_y = lv_obj_get_height(base) - obj_h_half; + break; + } + + /*Bring together the coordination system of base and obj*/ + lv_obj_t * par = lv_obj_get_parent(obj); + lv_coord_t base_abs_x = base->coords.x1; + lv_coord_t base_abs_y = base->coords.y1; + lv_coord_t par_abs_x = par->coords.x1; + lv_coord_t par_abs_y = par->coords.y1; + new_x += x_ofs + base_abs_x; + new_y += y_ofs + base_abs_y; + new_x -= par_abs_x; + new_y -= par_abs_y; + if(x_set && y_set) lv_obj_set_pos(obj, new_x, new_y); + else if(x_set) lv_obj_set_x(obj, new_x); + else if(y_set) lv_obj_set_y(obj, new_y); + +} + #if LV_USE_ANIMATION diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index c470e7af5..ad438c399 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -496,6 +496,25 @@ void lv_obj_align_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_ */ void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs); + +/** + * Align an object's middle point to an other object horizontally. + * @param obj pointer to an object to align + * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it. + * @param align type of alignment (see 'lv_align_t' enum) + * @param x_ofs x coordinate offset after alignment + */ +void lv_obj_align_origo_x(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs); + +/** + * Align an object's middle point to an other object vertically. + * @param obj pointer to an object to align + * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it. + * @param align type of alignment (see 'lv_align_t' enum) + * @param y_ofs y coordinate offset after alignment + */ +void lv_obj_align_origo_y(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t y_ofs); + /** * Realign the object based on the last `lv_obj_align` parameters. * @param obj pointer to an object