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:
parent
69ee8c48cc
commit
1f6af80817
@ -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")
|
||||
|
@ -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
|
||||
|
@ -77,6 +77,7 @@ local order = {
|
||||
taps_and_gestures = {
|
||||
"gesture_manager",
|
||||
"frontlight_gesture_controller",
|
||||
"gesture_intervals",
|
||||
"----------------------------",
|
||||
"menu_activate",
|
||||
"screen_disable_double_tab",
|
||||
|
@ -96,6 +96,7 @@ local order = {
|
||||
taps_and_gestures = {
|
||||
"gesture_manager",
|
||||
"frontlight_gesture_controller",
|
||||
"gesture_intervals",
|
||||
"----------------------------",
|
||||
"follow_links",
|
||||
"----------------------------",
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user