mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-23 09:43:41 +08:00
feat(switch): add vertical switch function (#6786)
Co-authored-by: lizhaoming <13678462+lizhao-ming@user.noreply.gitee.com> Co-authored-by: 100ask <support@100ask.net> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
7f57f37560
commit
a37f84f34c
@ -10,6 +10,8 @@ Overview
|
||||
The Switch looks like a little slider and can be used to turn something
|
||||
on and off.
|
||||
|
||||
Vertical Switch can be created if the width of the object is smaller than its height.
|
||||
|
||||
.. _lv_switch_parts_and_styles:
|
||||
|
||||
Parts and Styles
|
||||
@ -43,6 +45,12 @@ To get the current state of the switch (with ``true`` being on), use
|
||||
Call :cpp:expr:`lv_obj_add_state(obj, LV_STATE_CHECKED)` to turn it on, or
|
||||
:cpp:expr:`lv_obj_remove_state(obj, LV_STATE_CHECKED)` to turn it off.
|
||||
|
||||
Change orientation
|
||||
------------------
|
||||
|
||||
:cpp:expr:`lv_switch_set_orientation(obj, LV_SWITCH_ORIENTATION_VERTICAL)` change orientation, default orientation is :cpp:enumerator:`LV_SWITCH_ORIENTATION_AUTO`, adaptive based on the width and height of the object.
|
||||
|
||||
|
||||
.. _lv_switch_events:
|
||||
|
||||
Events
|
||||
|
@ -136,6 +136,7 @@ void lv_example_spinbox_1(void);
|
||||
void lv_example_spinner_1(void);
|
||||
|
||||
void lv_example_switch_1(void);
|
||||
void lv_example_switch_2(void);
|
||||
|
||||
void lv_example_table_1(void);
|
||||
void lv_example_table_2(void);
|
||||
|
@ -5,3 +5,10 @@ Simple Switch
|
||||
.. lv_example:: widgets/switch/lv_example_switch_1
|
||||
:language: c
|
||||
|
||||
|
||||
Switch Orientation
|
||||
-------------------
|
||||
|
||||
.. lv_example:: widgets/switch/lv_example_switch_2
|
||||
:language: c
|
||||
|
||||
|
32
examples/widgets/switch/lv_example_switch_2.c
Normal file
32
examples/widgets/switch/lv_example_switch_2.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_SWITCH && LV_BUILD_EXAMPLES
|
||||
|
||||
static void event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
LV_UNUSED(obj);
|
||||
LV_LOG_USER("State: %s\n", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "On" : "Off");
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_switch_2(void)
|
||||
{
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * sw;
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_obj_set_size(sw, 30, 60);
|
||||
lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_obj_set_size(sw, 30, 60);
|
||||
lv_switch_set_orientation(sw, LV_SWITCH_ORIENTATION_VERTICAL);
|
||||
lv_obj_add_state(sw, LV_STATE_CHECKED);
|
||||
lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
|
||||
}
|
||||
|
||||
#endif
|
@ -49,6 +49,7 @@ static void draw_main(lv_event_t * e);
|
||||
static void lv_switch_anim_exec_cb(void * sw, int32_t value);
|
||||
static void lv_switch_trigger_anim(lv_obj_t * obj);
|
||||
static void lv_switch_anim_completed(lv_anim_t * a);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@ -80,6 +81,31 @@ lv_obj_t * lv_switch_create(lv_obj_t * parent)
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_switch_t * sw = (lv_switch_t *)obj;
|
||||
|
||||
sw->orientation = orientation;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_switch_t * sw = (lv_switch_t *)obj;
|
||||
|
||||
return sw->orientation;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -92,6 +118,7 @@ static void lv_switch_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj
|
||||
lv_switch_t * sw = (lv_switch_t *)obj;
|
||||
|
||||
sw->anim_state = LV_SWITCH_ANIM_STATE_INV;
|
||||
sw->orientation = LV_SWITCH_ORIENTATION_AUTO;
|
||||
|
||||
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE);
|
||||
@ -163,28 +190,67 @@ static void draw_main(lv_event_t * e)
|
||||
lv_draw_rect(layer, &draw_indic_dsc, &indic_area);
|
||||
|
||||
/*Draw the knob*/
|
||||
int32_t anim_value_x = 0;
|
||||
int32_t knob_size = lv_obj_get_height(obj);
|
||||
int32_t anim_length = lv_area_get_width(&obj->coords) - knob_size;
|
||||
|
||||
if(LV_SWITCH_IS_ANIMATING(sw)) {
|
||||
/* Use the animation's coordinate */
|
||||
anim_value_x = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END;
|
||||
}
|
||||
else {
|
||||
/* Use LV_STATE_CHECKED to decide the coordinate */
|
||||
bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED;
|
||||
anim_value_x = chk ? anim_length : 0;
|
||||
}
|
||||
|
||||
if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) {
|
||||
anim_value_x = anim_length - anim_value_x;
|
||||
}
|
||||
|
||||
lv_area_t knob_area;
|
||||
lv_area_copy(&knob_area, &obj->coords);
|
||||
knob_area.x1 += anim_value_x;
|
||||
knob_area.x2 = knob_area.x1 + (knob_size > 0 ? knob_size - 1 : 0);
|
||||
|
||||
int32_t switch_w = lv_area_get_width(&obj->coords);
|
||||
int32_t switch_h = lv_area_get_height(&obj->coords);
|
||||
bool hor = false;
|
||||
|
||||
switch(sw->orientation) {
|
||||
case LV_SWITCH_ORIENTATION_HORIZONTAL:
|
||||
hor = true;
|
||||
break;
|
||||
case LV_SWITCH_ORIENTATION_VERTICAL:
|
||||
hor = false;
|
||||
break;
|
||||
case LV_SWITCH_ORIENTATION_AUTO:
|
||||
default:
|
||||
hor = (switch_w >= switch_h);
|
||||
break;
|
||||
}
|
||||
|
||||
if(hor) {
|
||||
int32_t anim_value_x = 0;
|
||||
int32_t knob_size = lv_obj_get_height(obj);
|
||||
int32_t anim_length = lv_area_get_width(&obj->coords) - knob_size;
|
||||
if(LV_SWITCH_IS_ANIMATING(sw)) {
|
||||
/* Use the animation's coordinate */
|
||||
anim_value_x = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END;
|
||||
}
|
||||
else {
|
||||
/* Use LV_STATE_CHECKED to decide the coordinate */
|
||||
bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED;
|
||||
anim_value_x = chk ? anim_length : 0;
|
||||
}
|
||||
|
||||
if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) {
|
||||
anim_value_x = anim_length - anim_value_x;
|
||||
}
|
||||
knob_area.x1 += anim_value_x;
|
||||
knob_area.x2 = knob_area.x1 + (knob_size > 0 ? knob_size - 1 : 0);
|
||||
}
|
||||
else {
|
||||
int32_t anim_value_y = 0;
|
||||
int32_t knob_size = lv_obj_get_width(obj);
|
||||
int32_t anim_length = lv_area_get_height(&obj->coords) - knob_size;
|
||||
if(LV_SWITCH_IS_ANIMATING(sw)) {
|
||||
/* Use the animation's coordinate */
|
||||
anim_value_y = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END;
|
||||
}
|
||||
else {
|
||||
/* Use LV_STATE_CHECKED to decide the coordinate */
|
||||
bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED;
|
||||
anim_value_y = chk ? anim_length : 0;
|
||||
}
|
||||
|
||||
if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) {
|
||||
anim_value_y = anim_length - anim_value_y;
|
||||
}
|
||||
|
||||
knob_area.y2 -= anim_value_y;
|
||||
knob_area.y1 = knob_area.y2 - (knob_size > 0 ? knob_size - 1 : 0);
|
||||
}
|
||||
|
||||
int32_t knob_left = lv_obj_get_style_pad_left(obj, LV_PART_KNOB);
|
||||
int32_t knob_right = lv_obj_get_style_pad_right(obj, LV_PART_KNOB);
|
||||
|
@ -28,6 +28,16 @@ extern "C" {
|
||||
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class;
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_SWITCH_ORIENTATION_AUTO,
|
||||
LV_SWITCH_ORIENTATION_HORIZONTAL,
|
||||
LV_SWITCH_ORIENTATION_VERTICAL
|
||||
} lv_switch_orientation_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -39,6 +49,28 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class;
|
||||
*/
|
||||
lv_obj_t * lv_switch_create(lv_obj_t * parent);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the orientation of switch.
|
||||
* @param obj pointer to switch object
|
||||
* @param orientation switch orientation from `lv_switch_orientation_t`
|
||||
*/
|
||||
void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the orientation of switch.
|
||||
* @param obj pointer to switch object
|
||||
* @return switch orientation from ::lv_switch_orientation_t
|
||||
*/
|
||||
lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -34,6 +34,7 @@ extern "C" {
|
||||
struct _lv_switch_t {
|
||||
lv_obj_t obj;
|
||||
int32_t anim_state;
|
||||
lv_switch_orientation_t orientation : 3; /**< Orientation of switch*/
|
||||
};
|
||||
|
||||
|
||||
|
BIN
tests/ref_imgs/widgets/switch_1.png
Normal file
BIN
tests/ref_imgs/widgets/switch_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
@ -133,4 +133,33 @@ void test_switch_should_state_change_when_event_bubbling_is_enabled(void)
|
||||
TEST_ASSERT(lv_obj_has_state(sw, LV_STATE_CHECKED));
|
||||
}
|
||||
|
||||
|
||||
void test_screeshots(void)
|
||||
{
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_clean(scr);
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_obj_add_state(sw, LV_STATE_CHECKED);
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_obj_add_state(sw, LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_switch_set_orientation(sw, LV_SWITCH_ORIENTATION_VERTICAL);
|
||||
lv_obj_set_size(sw, 50, 100);
|
||||
|
||||
sw = lv_switch_create(lv_screen_active());
|
||||
lv_switch_set_orientation(sw, LV_SWITCH_ORIENTATION_VERTICAL);
|
||||
lv_obj_add_state(sw, LV_STATE_CHECKED);
|
||||
lv_obj_set_size(sw, 50, 100);
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/switch_1.png");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user