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:
parent
1cb3e219a9
commit
54f9003722
@ -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
1033
docs/overview/style-props.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
----
|
||||
|
||||
|
@ -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
|
||||
------------------
|
||||
|
||||
|
@ -848,11 +848,12 @@
|
||||
/*Use SDL to open window on PC and handle mouse and keyboard*/
|
||||
#define LV_USE_SDL 0
|
||||
#if LV_USE_SDL
|
||||
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
|
||||
#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_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
|
||||
#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*/
|
||||
|
@ -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'},
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
**********************/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
**********************/
|
||||
|
@ -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;
|
||||
|
@ -2712,14 +2712,14 @@
|
||||
#ifdef CONFIG_LV_SDL_INCLUDE_PATH
|
||||
#define LV_SDL_INCLUDE_PATH CONFIG_LV_SDL_INCLUDE_PATH
|
||||
#else
|
||||
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_SDL_RENDER_MODE
|
||||
#ifdef CONFIG_LV_SDL_RENDER_MODE
|
||||
#define LV_SDL_RENDER_MODE CONFIG_LV_SDL_RENDER_MODE
|
||||
#else
|
||||
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
|
||||
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_SDL_BUF_COUNT
|
||||
@ -2730,14 +2730,14 @@
|
||||
#define LV_SDL_BUF_COUNT 0
|
||||
#endif
|
||||
#else
|
||||
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
|
||||
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_SDL_FULLSCREEN
|
||||
#ifdef CONFIG_LV_SDL_FULLSCREEN
|
||||
#define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN
|
||||
#else
|
||||
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
|
||||
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_SDL_DIRECT_EXIT
|
||||
@ -2748,7 +2748,14 @@
|
||||
#define LV_SDL_DIRECT_EXIT 0
|
||||
#endif
|
||||
#else
|
||||
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
|
||||
#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
|
||||
|
@ -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*/
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user