1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(indev) Add crown support to pointer input device (#5057)

This commit is contained in:
Gabor Kiss-Vamosi 2024-03-19 03:10:28 +01:00 committed by GitHub
parent 1cb3e219a9
commit 54f9003722
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 1313 additions and 93 deletions

View File

@ -214,6 +214,7 @@ static lv_obj_t * box_shadow_obj_create(lv_obj_t * parent, int32_t col, int32_t
lv_obj_t * obj = lv_obj_create(parent);
lv_obj_remove_style_all(obj);
lv_obj_set_style_bg_opa(obj, LV_OPA_20, 0);
lv_obj_set_style_bg_color(obj, lv_color_black(), 0);
lv_obj_set_style_shadow_color(obj, lv_color_hex3(0xf00), 0);
lv_obj_set_style_opa(obj, opa_saved, 0);
lv_obj_set_size(obj, DEF_WIDTH - 20, DEF_HEIGHT - 5);
@ -452,6 +453,7 @@ static lv_obj_t * arc_obj_create(lv_obj_t * parent, int32_t col, int32_t row, in
lv_obj_t * obj = lv_arc_create(parent);
lv_obj_remove_style_all(obj);
lv_obj_set_style_arc_width(obj, w, 0);
lv_obj_set_style_arc_color(obj, lv_color_white(), 0);
lv_obj_set_style_opa(obj, opa_saved, 0);
lv_arc_set_bg_angles(obj, start, end);
lv_obj_set_size(obj, DEF_HEIGHT, DEF_HEIGHT);

1033
docs/overview/style-props.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1378,6 +1378,20 @@ If set a layer will be created for the widget and the layer will be masked with
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
</ul>
rotary_sensitivity
~~~~~~~~~~~~~~~~~~
Adjust the sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change
.. raw:: html
<ul>
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `256`</li>
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> Yes</li>
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
</ul>
Flex
----

View File

@ -51,8 +51,41 @@ category.
}
}
Mouse cursor
~~~~~~~~~~~~
To set a mouse cursor use :cpp:expr:`lv_indev_set_cursor(indev, &img_cursor)`.
Crown behavior
~~~~~~~~~~~~~~
The "Crown" is a rotary device typically found on smart watches.
When the user clicks somewhere and after that turns the rotary
the last clicked widget will be either scrolled or it's value will be incremented/decremented
(e.g. in case of a slider).
As this behavior is tightly related to the last clicked widget, the crown support is
an extension of the pointer input device. Just set ``data->diff`` to the number of
turned steps and LVGL will automatically send :cpp:enum:`LV_EVENT_ROTARY` or scroll the widget based on the
``editable`` flag in the widget's class. Non-editable widgets are scrolled and for editable widgets the event is sent.
To get the steps in an event callback use :cpp:func:`int32_t diff = lv_event_get_rotary_diff(e)`
The rotary sensitivity can be adjusted on 2 levels:
1. In the input device by the `indev->rotary_sensitvity` element (1/256 unit)
2. By the `rotary_sensitivity` style property in the widget (1/256 unit)
The final diff is calculated like this:
``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256); ``
For example, if both the indev and widget sensitivity is set to 128 (0.5), the input diff. will be
multiplied by 0.25 (divided by 4). The value of the widget will be incremented by this value or
the widget will be scrolled this amount of pixels.
Keypad or keyboard
------------------

View File

@ -853,6 +853,7 @@
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
#define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/
#endif
/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/

View File

@ -393,6 +393,10 @@ props = [
'style_type': 'ptr', 'var_type': 'const lv_image_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
'dsc': "If set a layer will be created for the widget and the layer will be masked with this A8 bitmap mask."},
{'name': 'ROTARY_SENSITIVITY',
'style_type': 'num', 'var_type': 'uint32_t', 'default':'`256`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
'dsc': "Adjust the sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change"},
{'section': 'Flex', 'dsc':'Flex layout properties.', 'guard':'LV_USE_FLEX'},

View File

@ -242,6 +242,19 @@ uint32_t lv_event_get_key(lv_event_t * e)
}
}
int32_t lv_event_get_rotary_diff(lv_event_t * e)
{
if(e->code == LV_EVENT_ROTARY) {
int32_t * r = lv_event_get_param(e);
if(r) return *r;
else return 0;
}
else {
LV_LOG_WARN("Not interpreted with this event code");
return 0;
}
}
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e)
{
if(e->code == LV_EVENT_SCROLL_BEGIN) {

View File

@ -151,6 +151,13 @@ const lv_area_t * lv_event_get_old_size(lv_event_t * e);
*/
uint32_t lv_event_get_key(lv_event_t * e);
/**
* Get the signed rotary encoder diff. passed as parameter to an event. Can be used in `LV_EVENT_ROTARY`
* @param e pointer to an event
* @return the triggering key or NULL if called on an unrelated event
*/
int32_t lv_event_get_rotary_diff(lv_event_t * e);
/**
* Get the animation descriptor of a scrolling. Can be used in `LV_EVENT_SCROLL_BEGIN`
* @param e pointer to an event

View File

@ -320,70 +320,6 @@ void lv_obj_enable_style_refresh(bool en)
style_refr = en;
}
static inline lv_style_value_t lv_style_prop_get_default_inlined(lv_style_prop_t prop)
{
const lv_color_t black = LV_COLOR_MAKE(0x00, 0x00, 0x00);
const lv_color_t white = LV_COLOR_MAKE(0xff, 0xff, 0xff);
switch(prop) {
case LV_STYLE_TRANSFORM_SCALE_X:
case LV_STYLE_TRANSFORM_SCALE_Y:
return (lv_style_value_t) {
.num = LV_SCALE_NONE
};
case LV_STYLE_BG_COLOR:
return (lv_style_value_t) {
.color = black
};
case LV_STYLE_BG_GRAD_COLOR:
case LV_STYLE_BORDER_COLOR:
case LV_STYLE_SHADOW_COLOR:
case LV_STYLE_OUTLINE_COLOR:
case LV_STYLE_ARC_COLOR:
case LV_STYLE_LINE_COLOR:
case LV_STYLE_TEXT_COLOR:
case LV_STYLE_IMAGE_RECOLOR:
return (lv_style_value_t) {
.color = white
};
case LV_STYLE_OPA:
case LV_STYLE_OPA_LAYERED:
case LV_STYLE_BORDER_OPA:
case LV_STYLE_TEXT_OPA:
case LV_STYLE_IMAGE_OPA:
case LV_STYLE_BG_GRAD_OPA:
case LV_STYLE_BG_MAIN_OPA:
case LV_STYLE_BG_IMAGE_OPA:
case LV_STYLE_OUTLINE_OPA:
case LV_STYLE_SHADOW_OPA:
case LV_STYLE_LINE_OPA:
case LV_STYLE_ARC_OPA:
return (lv_style_value_t) {
.num = LV_OPA_COVER
};
case LV_STYLE_BG_GRAD_STOP:
return (lv_style_value_t) {
.num = 255
};
case LV_STYLE_BORDER_SIDE:
return (lv_style_value_t) {
.num = LV_BORDER_SIDE_FULL
};
case LV_STYLE_TEXT_FONT:
return (lv_style_value_t) {
.ptr = LV_FONT_DEFAULT
};
case LV_STYLE_MAX_WIDTH:
case LV_STYLE_MAX_HEIGHT:
return (lv_style_value_t) {
.num = LV_COORD_MAX
};
default:
return (lv_style_value_t) {
.ptr = 0
};
}
}
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
{
LV_ASSERT_NULL(obj)
@ -395,7 +331,7 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_
found = get_selector_style_prop(obj, selector, prop, &value_act);
if(found == LV_STYLE_RES_FOUND) return value_act;
return lv_style_prop_get_default_inlined(prop);
return lv_style_prop_get_default(prop);
}
bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop)

View File

@ -761,6 +761,14 @@ void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const lv_image_dsc_t * val
};
lv_obj_set_local_style_prop(obj, LV_STYLE_BITMAP_MASK_SRC, v, selector);
}
void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
{
lv_style_value_t v = {
.num = (int32_t)value
};
lv_obj_set_local_style_prop(obj, LV_STYLE_ROTARY_SENSITIVITY, v, selector);
}
#if LV_USE_FLEX
void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector)

View File

@ -642,6 +642,12 @@ static inline const lv_image_dsc_t * lv_obj_get_style_bitmap_mask_src(const lv_o
return (const lv_image_dsc_t *)v.ptr;
}
static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, uint32_t part)
{
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ROTARY_SENSITIVITY);
return (uint32_t)v.num;
}
#if LV_USE_FLEX
static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, uint32_t part)
{
@ -832,6 +838,7 @@ void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style
void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector);
void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector);
void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const lv_image_dsc_t * value, lv_style_selector_t selector);
void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
#if LV_USE_FLEX
void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector);
void lv_obj_set_style_flex_main_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector);

View File

@ -35,6 +35,9 @@ typedef struct {
int16_t last_x;
int16_t last_y;
bool left_button_down;
#if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN
int32_t diff;
#endif
} lv_sdl_mouse_t;
/**********************
@ -76,6 +79,10 @@ static void sdl_mouse_read(lv_indev_t * indev, lv_indev_data_t * data)
data->point.x = dsc->last_x;
data->point.y = dsc->last_y;
data->state = dsc->left_button_down ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
#if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN
data->enc_diff = dsc->diff;
dsc->diff = 0;
#endif
}
static void release_indev_cb(lv_event_t * e)
@ -101,7 +108,11 @@ void _lv_sdl_mouse_handler(SDL_Event * event)
case SDL_MOUSEMOTION:
win_id = event->motion.windowID;
break;
#if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN
case SDL_MOUSEWHEEL:
win_id = event->wheel.windowID;
break;
#endif
case SDL_FINGERUP:
case SDL_FINGERDOWN:
case SDL_FINGERMOTION:
@ -174,6 +185,17 @@ void _lv_sdl_mouse_handler(SDL_Event * event)
indev_dev->last_x = (int16_t)((float)hor_res * event->tfinger.x / zoom);
indev_dev->last_y = (int16_t)((float)ver_res * event->tfinger.y / zoom);
break;
case SDL_MOUSEWHEEL:
#if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN
#ifdef __EMSCRIPTEN__
/*Escripten scales it wrong*/
if(event->wheel.y < 0) dsc->diff++;
if(event->wheel.y > 0) dsc->diff--;
#else
indev_dev->diff = -event->wheel.y;
#endif /*__EMSCRIPTEN__*/
#endif /*LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN*/
break;
}
lv_indev_read(indev);
}

View File

@ -7,7 +7,7 @@
* INCLUDES
*********************/
#include "lv_sdl_mousewheel.h"
#if LV_USE_SDL
#if LV_USE_SDL && LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER
#include "../../core/lv_group.h"
#include "../../indev/lv_indev_private.h"

View File

@ -14,7 +14,7 @@ extern "C" {
* INCLUDES
*********************/
#include "lv_sdl_window.h"
#if LV_USE_SDL
#if LV_USE_SDL && LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER
/*********************
* DEFINES

View File

@ -253,7 +253,9 @@ static void sdl_event_handler(lv_timer_t * t)
SDL_Event event;
while(SDL_PollEvent(&event)) {
_lv_sdl_mouse_handler(&event);
#if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER
_lv_sdl_mousewheel_handler(&event);
#endif
_lv_sdl_keyboard_handler(&event);
if(event.type == SDL_WINDOWEVENT) {

View File

@ -23,6 +23,10 @@ extern "C" {
* DEFINES
*********************/
/* Possible values of LV_SDL_MOUSEWHEEL_MODE */
#define LV_SDL_MOUSEWHEEL_MODE_ENCODER 0 /* The mousewheel emulates an encoder input device*/
#define LV_SDL_MOUSEWHEEL_MODE_CROWN 1 /* The mousewheel emulates a smart watch crown*/
/**********************
* TYPEDEFS
**********************/

View File

@ -43,6 +43,9 @@
/*Gesture min velocity at release before swipe (pixels)*/
#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3
/**< Rotary diff count will be multiplied by this and divided by 256 */
#define LV_INDEV_DEF_ROTARY_SENSITIVITY 256
#if LV_INDEV_DEF_SCROLL_THROW <= 0
#warning "LV_INDEV_DEF_SCROLL_THROW must be greater than 0"
#endif
@ -64,6 +67,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data);
static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data);
static void indev_proc_press(lv_indev_t * indev);
static void indev_proc_release(lv_indev_t * indev);
static void indev_proc_pointer_diff(lv_indev_t * indev);
static lv_obj_t * pointer_search_obj(lv_display_t * disp, lv_point_t * p);
static void indev_proc_reset_query_handler(lv_indev_t * indev);
static void indev_click_focus(lv_indev_t * indev);
@ -130,6 +134,7 @@ lv_indev_t * lv_indev_create(void)
indev->long_press_repeat_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
indev->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
indev->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY;
indev->rotary_sensitvity = LV_INDEV_DEF_ROTARY_SENSITIVITY;
return indev;
}
@ -660,6 +665,10 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
i->pointer.act_point.x = data->point.x;
i->pointer.act_point.y = data->point.y;
i->pointer.diff = data->enc_diff;
/*Process the diff first as scrolling will be processed in indev_proc_release*/
indev_proc_pointer_diff(i);
if(i->state == LV_INDEV_STATE_PRESSED) {
indev_proc_press(i);
@ -670,6 +679,7 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
i->pointer.last_point.x = i->pointer.act_point.x;
i->pointer.last_point.y = i->pointer.act_point.y;
}
/**
@ -1117,8 +1127,9 @@ static void indev_proc_press(lv_indev_t * indev)
if(new_obj_searched && indev->pointer.scroll_obj) {
/*Attempt to stop scroll throw animation firstly*/
if(!indev->scroll_throw_anim || !lv_anim_delete(indev, indev_scroll_throw_anim_cb)) {
indev_scroll_throw_anim_reset(indev);
if(indev->scroll_throw_anim) {
lv_anim_delete(indev, indev_scroll_throw_anim_cb);
indev->scroll_throw_anim = NULL;
}
_lv_indev_scroll_throw_handler(indev);
@ -1301,7 +1312,6 @@ static void indev_proc_release(lv_indev_t * indev)
lv_point_transform(&indev->pointer.scroll_throw_vect_ori, angle, scale_x, scale_y, &pivot, false);
}
}
}
if(scroll_obj) {
@ -1313,6 +1323,40 @@ static void indev_proc_release(lv_indev_t * indev)
}
}
static void indev_proc_pointer_diff(lv_indev_t * indev)
{
lv_obj_t * obj = indev->pointer.last_pressed;
if(obj == NULL) return;
if(indev->pointer.diff == 0) return;
indev_obj_act = obj;
bool editable = lv_obj_is_editable(obj);
if(editable) {
uint32_t indev_sensitivity = indev->rotary_sensitvity;
uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(indev_obj_act, 0);
int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16;
send_event(LV_EVENT_ROTARY, &diff);
}
else {
int32_t vect = indev->pointer.diff > 0 ? indev->scroll_limit : -indev->scroll_limit;
indev->pointer.vect.y = vect;
indev->pointer.act_obj = obj;
lv_obj_t * scroll_obj = lv_indev_find_scroll_obj(indev);
if(scroll_obj == NULL) return;
uint32_t indev_sensitivity = indev->rotary_sensitvity;
uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(scroll_obj, 0);
int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16;
indev->pointer.scroll_throw_vect.y = diff;
indev->pointer.scroll_throw_vect_ori.y = diff;
_lv_indev_scroll_handler(indev);
}
}
static lv_obj_t * pointer_search_obj(lv_display_t * disp, lv_point_t * p)
{
indev_obj_act = lv_indev_search_obj(lv_display_get_layer_sys(disp), p);
@ -1545,7 +1589,8 @@ static lv_result_t send_event(lv_event_code_t code, void * param)
code == LV_EVENT_CLICKED ||
code == LV_EVENT_RELEASED ||
code == LV_EVENT_LONG_PRESSED ||
code == LV_EVENT_LONG_PRESSED_REPEAT) {
code == LV_EVENT_LONG_PRESSED_REPEAT ||
code == LV_EVENT_ROTARY) {
lv_indev_send_event(indev_act, code, indev_obj_act);
if(indev_reset_check(indev_act)) return LV_RESULT_INVALID;
}

View File

@ -69,6 +69,9 @@ struct _lv_indev_t {
/**< Repeated trigger period in long press [ms]*/
uint16_t long_press_repeat_time;
/**< Rotary diff count will be multiplied by this value and divided by 256*/
int32_t rotary_sensitvity;
struct {
/*Pointer and button data*/
lv_point_t act_point; /**< Current point of input device.*/
@ -84,6 +87,7 @@ struct _lv_indev_t {
lv_obj_t * last_pressed; /*The lastly pressed object*/
lv_area_t scroll_area;
lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
int32_t diff;
/*Flags*/
lv_dir_t scroll_dir : 4;
@ -100,14 +104,22 @@ struct _lv_indev_t {
lv_group_t * group; /**< Keypad destination group*/
const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed
here by the buttons*/
lv_event_list_t event_list;
lv_anim_t * scroll_throw_anim;
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Find a scrollable object based on the current scroll vector in the indev.
* In handles scroll propagation to the parent if needed, and scroll directions too.
* @param indev pointer to an indev
* @return the found scrollable object or NULL if not found.
*/
lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev);
/**********************
* MACROS
**********************/

View File

@ -22,7 +22,6 @@
/**********************
* STATIC PROTOTYPES
**********************/
static lv_obj_t * find_scroll_obj(lv_indev_t * indev);
static void init_scroll_limits(lv_indev_t * indev);
static int32_t find_snap_point_x(const lv_obj_t * obj, int32_t min, int32_t max, int32_t ofs);
static int32_t find_snap_point_y(const lv_obj_t * obj, int32_t min, int32_t max, int32_t ofs);
@ -51,7 +50,7 @@ void _lv_indev_scroll_handler(lv_indev_t * indev)
lv_obj_t * scroll_obj = indev->pointer.scroll_obj;
/*If there is no scroll object yet try to find one*/
if(scroll_obj == NULL) {
scroll_obj = find_scroll_obj(indev);
scroll_obj = lv_indev_find_scroll_obj(indev);
if(scroll_obj == NULL) return;
init_scroll_limits(indev);
@ -254,11 +253,7 @@ void lv_indev_scroll_get_snap_dist(lv_obj_t * obj, lv_point_t * p)
p->y = find_snap_point_y(obj, obj->coords.y1, obj->coords.y2, 0);
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_obj_t * find_scroll_obj(lv_indev_t * indev)
lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev)
{
lv_obj_t * obj_candidate = NULL;
lv_dir_t dir_candidate = LV_DIR_NONE;
@ -389,6 +384,10 @@ static lv_obj_t * find_scroll_obj(lv_indev_t * indev)
return obj_candidate;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void init_scroll_limits(lv_indev_t * indev)
{
lv_obj_t * obj = indev->pointer.scroll_obj;

View File

@ -2751,6 +2751,13 @@
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
#endif
#endif
#ifndef LV_SDL_MOUSEWHEEL_MODE
#ifdef CONFIG_LV_SDL_MOUSEWHEEL_MODE
#define LV_SDL_MOUSEWHEEL_MODE CONFIG_LV_SDL_MOUSEWHEEL_MODE
#else
#define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/
#endif
#endif
#endif
/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/

View File

@ -57,6 +57,7 @@ typedef enum {
LV_EVENT_SCROLL, /**< Scrolling*/
LV_EVENT_GESTURE, /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */
LV_EVENT_KEY, /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_active());`*/
LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get the rotation count with `lv_event_get_rotary_diff(e);`*/
LV_EVENT_FOCUSED, /**< The object is focused*/
LV_EVENT_DEFOCUSED, /**< The object is defocused*/
LV_EVENT_LEAVE, /**< The object is defocused but still selected*/

View File

@ -406,9 +406,13 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop)
return (lv_style_value_t) {
.num = LV_COORD_MAX
};
case LV_STYLE_ROTARY_SENSITIVITY:
return (lv_style_value_t) {
.num = 256
};
default:
return (lv_style_value_t) {
.ptr = 0
.ptr = NULL
};
}
}

View File

@ -298,8 +298,8 @@ enum _lv_style_prop_t {
LV_STYLE_TRANSFORM_PIVOT_Y = 112,
LV_STYLE_TRANSFORM_SKEW_X = 113,
LV_STYLE_TRANSFORM_SKEW_Y = 114,
LV_STYLE_BITMAP_MASK_SRC = 115,
LV_STYLE_ROTARY_SENSITIVITY = 116,
#if LV_USE_FLEX
LV_STYLE_FLEX_FLOW = 125,

View File

@ -949,6 +949,16 @@ void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * val
}
const lv_style_prop_t _lv_style_const_prop_id_BITMAP_MASK_SRC = LV_STYLE_BITMAP_MASK_SRC;
void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value)
{
lv_style_value_t v = {
.num = (int32_t)value
};
lv_style_set_prop(style, LV_STYLE_ROTARY_SENSITIVITY, v);
}
const lv_style_prop_t _lv_style_const_prop_id_ROTARY_SENSITIVITY = LV_STYLE_ROTARY_SENSITIVITY;
#if LV_USE_FLEX
void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value)

View File

@ -202,6 +202,8 @@ void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value);
LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BASE_DIR;
void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * value);
LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BITMAP_MASK_SRC;
void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value);
LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ROTARY_SENSITIVITY;
#if LV_USE_FLEX
void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value);
LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_FLOW;
@ -708,6 +710,11 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GR
{ \
.prop_ptr = &_lv_style_const_prop_id_BITMAP_MASK_SRC, .value = { .ptr = val } \
}
#define LV_STYLE_CONST_ROTARY_SENSITIVITY(val) \
{ \
.prop_ptr = &_lv_style_const_prop_id_ROTARY_SENSITIVITY, .value = { .num = (int32_t)val } \
}
#if LV_USE_FLEX
#define LV_STYLE_CONST_FLEX_FLOW(val) \

View File

@ -75,6 +75,7 @@ typedef struct {
lv_style_t circle;
lv_style_t no_radius;
lv_style_t clip_corner;
lv_style_t rotary_scroll;
#if LV_THEME_DEFAULT_GROW
lv_style_t grow;
#endif
@ -263,6 +264,7 @@ static void style_init(my_theme_t * theme)
lv_style_set_text_font(&theme->styles.scr, theme->base.font_normal);
lv_style_set_pad_row(&theme->styles.scr, PAD_SMALL);
lv_style_set_pad_column(&theme->styles.scr, PAD_SMALL);
lv_style_set_rotary_sensitivity(&theme->styles.scr, theme->disp_dpi / 4 * 256);
style_init_reset(&theme->styles.card);
lv_style_set_radius(&theme->styles.card, RADIUS_DEFAULT);
@ -386,6 +388,9 @@ static void style_init(my_theme_t * theme)
style_init_reset(&theme->styles.no_radius);
lv_style_set_radius(&theme->styles.no_radius, 0);
style_init_reset(&theme->styles.rotary_scroll);
lv_style_set_rotary_sensitivity(&theme->styles.rotary_scroll, theme->disp_dpi / 4 * 256);
#if LV_THEME_DEFAULT_GROW
style_init_reset(&theme->styles.grow);
lv_style_set_transform_width(&theme->styles.grow, _LV_DPX_CALC(theme->disp_dpi, 3));
@ -747,6 +752,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
/*Tabview pages*/
else if(parent && lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) {
lv_obj_add_style(obj, &theme->styles.pad_normal, 0);
lv_obj_add_style(obj, &theme->styles.rotary_scroll, 0);
lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
lv_obj_add_style(obj, &theme->styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED);
return;

View File

@ -605,7 +605,7 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
else if(code == LV_EVENT_KEY) {
uint32_t c = lv_event_get_key(e);
int16_t old_value = arc->value;
int32_t old_value = arc->value;
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
lv_arc_set_value(obj, lv_arc_get_value(obj) + 1);
}
@ -618,6 +618,16 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
if(res != LV_RESULT_OK) return;
}
}
else if(code == LV_EVENT_ROTARY) {
int32_t r = lv_event_get_rotary_diff(e);
int32_t old_value = arc->value;
lv_arc_set_value(obj, lv_arc_get_value(obj) + r);
if(old_value != arc->value) {
res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RESULT_OK) return;
}
}
else if(code == LV_EVENT_HIT_TEST) {
lv_hit_test_info_t * info = lv_event_get_param(e);

View File

@ -738,6 +738,19 @@ static void lv_dropdown_event(const lv_obj_class_t * class_p, lv_event_t * e)
}
}
}
else if(code == LV_EVENT_ROTARY) {
if(!lv_dropdown_is_open(obj)) {
lv_dropdown_open(obj);
}
else {
int32_t r = lv_event_get_rotary_diff(e);
int32_t new_id = dropdown->sel_opt_id + r;
new_id = LV_CLAMP(0, new_id, (int32_t)dropdown->option_cnt - 1);
dropdown->sel_opt_id = new_id;
position_to_selected(obj);
}
}
else if(code == LV_EVENT_DRAW_MAIN) {
draw_main(e);
}

View File

@ -380,6 +380,16 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e)
}
}
}
else if(code == LV_EVENT_ROTARY) {
int32_t r = lv_event_get_rotary_diff(e);
int32_t new_id = roller->sel_opt_id + r;
new_id = LV_CLAMP(0, new_id, (int32_t)roller->option_cnt - 1);
if((int32_t)roller->sel_opt_id != new_id) {
uint32_t ori_id = roller->sel_opt_id_ori; /*lv_roller_set_selected will overwrite this*/
lv_roller_set_selected(obj, new_id, LV_ANIM_ON);
roller->sel_opt_id_ori = ori_id;
}
}
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
lv_obj_t * label = get_label(obj);
lv_obj_refresh_ext_draw_size(label);

View File

@ -224,6 +224,15 @@ static void lv_slider_event(const lv_obj_class_t * class_p, lv_event_t * e)
res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RESULT_OK) return;
}
else if(code == LV_EVENT_ROTARY) {
int32_t r = lv_event_get_rotary_diff(e);
if(!slider->left_knob_focus) lv_slider_set_value(obj, lv_slider_get_value(obj) + r, LV_ANIM_ON);
else lv_slider_set_left_value(obj, lv_slider_get_left_value(obj) + 1, LV_ANIM_ON);
res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RESULT_OK) return;
}
else if(code == LV_EVENT_DRAW_MAIN) {
draw_knob(e);
}

View File

@ -21,6 +21,7 @@ static lv_obj_t * img_create(void)
lv_obj_t * img = lv_image_create(lv_screen_active());
lv_image_set_src(img, &test_img_lvgl_logo_png);
lv_obj_set_style_bg_opa(img, LV_OPA_20, 0);
lv_obj_set_style_bg_color(img, lv_color_hex(0x000000), 0);
lv_obj_set_style_shadow_width(img, 10, 0);
lv_obj_set_style_shadow_color(img, lv_color_hex(0xff0000), 0);
return img;