2
0
mirror of https://github.com/koreader/koreader synced 2024-11-10 01:10:34 +00:00

[feat] Make gesture intervals configurable (#5138)

Discussion: #4842
Close: #4842
This commit is contained in:
Robert 2019-07-24 14:31:20 +02:00 committed by Frans de Jonge
parent 69ee8c48cc
commit 1f6af80817
5 changed files with 200 additions and 8 deletions

View File

@ -359,6 +359,146 @@ function ReaderGesture:addToMainMenu(menu_items)
},
},
}
menu_items.gesture_intervals = {
text = _("Gesture intervals"),
sub_item_table = {
{
text = _("Double tap interval"),
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local GestureDetector = require("device/gesturedetector")
local items = SpinWidget:new{
text = T(_([[
Set double tap interval in miliseconds.
The interval value can range from 100 (0.1 seconds) to 2000 (2 seconds).
Default value: %1]]), GestureDetector.DOUBLE_TAP_INTERVAL/1000),
width = Screen:getWidth() * 0.6,
value = GestureDetector:getInterval("ges_double_tap_interval")/1000,
value_min = 100,
value_max = 2000,
value_step = 100,
value_hold_step = 500,
ok_text = _("Set interval"),
title_text = _("Double tap interval"),
default_value = GestureDetector.DOUBLE_TAP_INTERVAL/1000,
callback = function(spin)
G_reader_settings:saveSetting("ges_double_tap_interval", spin.value*1000)
GestureDetector:setNewInterval("ges_double_tap_interval", spin.value*1000)
end
}
UIManager:show(items)
end,
},
{
text = _("Two finger tap duration"),
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local GestureDetector = require("device/gesturedetector")
local items = SpinWidget:new{
text = T(_([[
Set two finger tap duration in miliseconds.
The duration value can range from 100 (0.1 seconds) to 2000 (2 seconds).
Default value: %1]]), GestureDetector.TWO_FINGER_TAP_DURATION/1000),
width = Screen:getWidth() * 0.6,
value = GestureDetector:getInterval("ges_two_finger_tap_duration")/1000,
value_min = 100,
value_max = 2000,
value_step = 100,
value_hold_step = 500,
ok_text = _("Set duration"),
title_text = _("Two finger tap duration"),
default_value = GestureDetector.TWO_FINGER_TAP_DURATION/1000,
callback = function(spin)
G_reader_settings:saveSetting("ges_two_finger_tap_duration", spin.value*1000)
GestureDetector:setNewInterval("ges_two_finger_tap_duration", spin.value*1000)
end
}
UIManager:show(items)
end,
},
{
text = _("Hold interval"),
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local GestureDetector = require("device/gesturedetector")
local items = SpinWidget:new{
text = T(_([[
Set hold interval in miliseconds.
The interval value can range from 100 (0.1 seconds) to 2000 (2 seconds).
Default value: %1]]), GestureDetector.HOLD_INTERVAL/1000),
width = Screen:getWidth() * 0.6,
value = GestureDetector:getInterval("ges_hold_interval")/1000,
value_min = 100,
value_max = 2000,
value_step = 100,
value_hold_step = 500,
ok_text = _("Set interval"),
title_text = _("Hold interval"),
default_value = GestureDetector.HOLD_INTERVAL/1000,
callback = function(spin)
G_reader_settings:saveSetting("ges_hold_interval", spin.value*1000)
GestureDetector:setNewInterval("ges_hold_interval", spin.value*1000)
end
}
UIManager:show(items)
end,
},
{
text = _("Pan delay interval"),
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local GestureDetector = require("device/gesturedetector")
local items = SpinWidget:new{
text = T(_([[
Set pan delay interval in miliseconds.
The interval value can range from 100 (0.1 seconds) to 2000 (2 seconds).
Default value: %1]]), GestureDetector.PAN_DELAYED_INTERVAL/1000),
width = Screen:getWidth() * 0.6,
value = GestureDetector:getInterval("ges_pan_delayed_interval")/1000,
value_min = 100,
value_max = 2000,
value_step = 100,
value_hold_step = 500,
ok_text = _("Set interval"),
title_text = _("Pan delay interval"),
default_value = GestureDetector.PAN_DELAYED_INTERVAL/1000,
callback = function(spin)
G_reader_settings:saveSetting("ges_pan_delayed_interval", spin.value*1000)
GestureDetector:setNewInterval("ges_pan_delayed_interval", spin.value*1000)
end
}
UIManager:show(items)
end,
},
{
text = _("Swipe interval"),
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local GestureDetector = require("device/gesturedetector")
local items = SpinWidget:new{
text = T(_([[
Set swipe interval in miliseconds.
The interval value can range from 100 (0.1 seconds) to 2000 (2 seconds).
Default value: %1]]), GestureDetector.SWIPE_INTERVAL/1000),
width = Screen:getWidth() * 0.6,
value = GestureDetector:getInterval("ges_swipe_interval")/1000,
value_min = 100,
value_max = 2000,
value_step = 100,
value_hold_step = 500,
ok_text = _("Set interval"),
title_text = _("Swipe interval"),
default_value = GestureDetector.SWIPE_INTERVAL/1000,
callback = function(spin)
G_reader_settings:saveSetting("ges_swipe_interval", spin.value*1000)
GestureDetector:setNewInterval("ges_swipe_interval", spin.value*1000)
end
}
UIManager:show(items)
end,
},
}
}
local twoFingerSwipeTextFunc = function(gesture, friendly_name)
local action_name = gesture_manager[gesture] ~= "nothing" and action_strings[gesture_manager[gesture]] or _("Available")

View File

@ -47,10 +47,17 @@ local TimeVal = require("ui/timeval")
local logger = require("logger")
local util = require("util")
-- all the time parameters are in us
local ges_double_tap_interval = G_reader_settings:readSetting("ges_double_tap_interval") or 300 * 1000
local ges_two_finger_tap_duration = G_reader_settings:readSetting("ges_two_finger_tap_duration") or 300 * 1000
local ges_hold_interval = G_reader_settings:readSetting("ges_hold_interval") or 500 * 1000
local ges_pan_delayed_interval = G_reader_settings:readSetting("ges_pan_delayed_interval") or 500 * 1000
local ges_swipe_interval = G_reader_settings:readSetting("ges_swipe_interval") or 900 * 1000
local GestureDetector = {
-- must be initialized with the Input singleton class
input = nil,
-- all the time parameters are in us
-- default values (all the time parameters are in us)
DOUBLE_TAP_INTERVAL = 300 * 1000,
TWO_FINGER_TAP_DURATION = 300 * 1000,
HOLD_INTERVAL = 500 * 1000,
@ -141,7 +148,7 @@ function GestureDetector:isDoubleTap(tap1, tap2)
return (
math.abs(tap1.x - tap2.x) < self.DOUBLE_TAP_DISTANCE and
math.abs(tap1.y - tap2.y) < self.DOUBLE_TAP_DISTANCE and
(tv_diff.sec == 0 and (tv_diff.usec) < self.DOUBLE_TAP_INTERVAL)
(tv_diff.sec == 0 and (tv_diff.usec) < ges_double_tap_interval)
)
end
@ -160,8 +167,8 @@ function GestureDetector:isTwoFingerTap()
x_diff1 < self.TWO_FINGER_TAP_REGION and
y_diff0 < self.TWO_FINGER_TAP_REGION and
y_diff1 < self.TWO_FINGER_TAP_REGION and
tv_diff0.sec == 0 and tv_diff0.usec < self.TWO_FINGER_TAP_DURATION and
tv_diff1.sec == 0 and tv_diff1.usec < self.TWO_FINGER_TAP_DURATION
tv_diff0.sec == 0 and tv_diff0.usec < ges_two_finger_tap_duration and
tv_diff1.sec == 0 and tv_diff1.usec < ges_two_finger_tap_duration
)
end
@ -200,7 +207,7 @@ end
function GestureDetector:isSwipe(slot)
if not self.first_tevs[slot] or not self.last_tevs[slot] then return end
local tv_diff = self.last_tevs[slot].timev - self.first_tevs[slot].timev
if (tv_diff.sec == 0) and (tv_diff.usec < self.SWIPE_INTERVAL) then
if (tv_diff.sec == 0) and (tv_diff.usec < ges_swipe_interval) then
local x_diff = self.last_tevs[slot].x - self.first_tevs[slot].x
local y_diff = self.last_tevs[slot].y - self.first_tevs[slot].y
if x_diff ~= 0 or y_diff ~= 0 then
@ -234,6 +241,34 @@ function GestureDetector:clearState(slot)
self.multiswipe_type = nil
end
function GestureDetector:setNewInterval(type, interval)
if type == "ges_double_tap_interval" then
ges_double_tap_interval = interval
elseif type == "ges_two_finger_tap_duration" then
ges_two_finger_tap_duration = interval
elseif type == "ges_hold_interval" then
ges_hold_interval = interval
elseif type == "ges_pan_delayed_interval" then
ges_pan_delayed_interval = interval
elseif type == "ges_swipe_interval" then
ges_swipe_interval = interval
end
end
function GestureDetector:getInterval(type)
if type == "ges_double_tap_interval" then
return ges_double_tap_interval
elseif type == "ges_two_finger_tap_duration" then
return ges_two_finger_tap_duration
elseif type == "ges_hold_interval" then
return ges_hold_interval
elseif type == "ges_pan_delayed_interval" then
return ges_pan_delayed_interval
elseif type == "ges_swipe_interval" then
return ges_swipe_interval
end
end
function GestureDetector:clearStates()
self:clearState(0)
self:clearState(1)
@ -348,7 +383,7 @@ function GestureDetector:handleDoubleTap(tev)
-- deadline should be calculated by adding current tap time and the interval
local deadline = cur_tap.timev + TimeVal:new{
sec = 0,
usec = not self.input.disable_double_tap and self.DOUBLE_TAP_INTERVAL or 0,
usec = not self.input.disable_double_tap and ges_double_tap_interval or 0,
}
self.input:setTimeout(function()
logger.dbg("in tap timer", self.last_taps[slot] ~= nil)
@ -374,7 +409,7 @@ function GestureDetector:handleNonTap(tev)
self.states[slot] = self.tapState
logger.dbg("set up hold timer")
local deadline = tev.timev + TimeVal:new{
sec = 0, usec = self.HOLD_INTERVAL
sec = 0, usec = ges_hold_interval
}
self.input:setTimeout(function()
if self.states[slot] == self.tapState then
@ -514,7 +549,7 @@ function GestureDetector:handlePan(tev)
-- delayed pan, used where necessary to reduce potential activation of panning
-- when swiping is intended (e.g., for the menu or for multiswipe)
if not ((tv_diff.sec == 0) and (tv_diff.usec < self.PAN_DELAYED_INTERVAL)) then
if not ((tv_diff.sec == 0) and (tv_diff.usec < ges_pan_delayed_interval)) then
pan_ev.relative_delayed.x = tev.x - self.first_tevs[slot].x
pan_ev.relative_delayed.y = tev.y - self.first_tevs[slot].y
pan_ev.distance_delayed = pan_distance

View File

@ -77,6 +77,7 @@ local order = {
taps_and_gestures = {
"gesture_manager",
"frontlight_gesture_controller",
"gesture_intervals",
"----------------------------",
"menu_activate",
"screen_disable_double_tab",

View File

@ -96,6 +96,7 @@ local order = {
taps_and_gestures = {
"gesture_manager",
"frontlight_gesture_controller",
"gesture_intervals",
"----------------------------",
"follow_links",
"----------------------------",

View File

@ -33,6 +33,9 @@ local SpinWidget = InputContainer:new{
value_hold_step = 4,
ok_text = _("OK"),
cancel_text = _("Cancel"),
-- set this to see extra default button
default_value = nil,
defaults_text = _("Use default"),
}
function SpinWidget:init()
@ -123,6 +126,18 @@ function SpinWidget:update()
}
}
if self.default_value then
table.insert(buttons,{
{
text = self.defaults_text,
callback = function()
value_widget.value = self.default_value
value_widget:update()
end,
},
})
end
local ok_cancel_buttons = ButtonTable:new{
width = self.width - 2*Size.padding.default,
buttons = buttons,