mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
[DictQuickLookup] NT: add text selection to the dictionary widget (#13232)
Initially, when you open the dictionary widget from the reader, FocusManager will function as usual. On Kindle 4 or devices with a keyboard, I have assigned the shortcuts <kbd>screenkb</kbd> + <kbd>up</kbd>/<kbd>down</kbd> or <kbd>shift</kbd> + <kbd>up</kbd>/<kbd>down</kbd> to initiate text selection (as a remainder, on kindle text selection in reader is initiated with <kbd>up</kbd>/<kbd>down</kbd> so it is fairly similar). At this point, FocusManager is disabled, allowing the cursor keys (and press) to control the now-visible crosshairs. Pressing <kbd>back</kbd> should stop text selection and restore FocusManager’s control of the widget.
This commit is contained in:
@@ -3,6 +3,7 @@ local BlitBuffer = require("ffi/blitbuffer")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local Device = require("device")
|
||||
local DoubleSpinWidget = require("ui/widget/doublespinwidget")
|
||||
local Event = require("ui/event")
|
||||
local Geom = require("ui/geometry")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
@@ -798,25 +799,39 @@ Except when in two columns mode, where this is limited to showing only the previ
|
||||
if not Device:isTouchDevice() and Device:hasDPad() then
|
||||
table.insert(menu_items.long_press.sub_item_table, {
|
||||
text_func = function()
|
||||
return T(_("Crosshairs speed for text selection: %1"), G_reader_settings:readSetting("highlight_non_touch_factor") or 4)
|
||||
local reader_speed = G_reader_settings:readSetting("highlight_non_touch_factor") or 4
|
||||
local dict_speed = G_reader_settings:readSetting("highlight_non_touch_factor_dict") or 3
|
||||
return T(_("Crosshairs speed (reader/dict): %1 / %2"), reader_speed, dict_speed)
|
||||
end,
|
||||
callback = function(touchmenu_instance)
|
||||
local curr_val = G_reader_settings:readSetting("highlight_non_touch_factor") or 4
|
||||
local spin_widget = SpinWidget:new{
|
||||
value = curr_val,
|
||||
value_min = 0.25,
|
||||
value_max = 5,
|
||||
precision = "%.2f",
|
||||
value_step = 0.25,
|
||||
default_value = 4,
|
||||
local reader_speed = G_reader_settings:readSetting("highlight_non_touch_factor") or 4
|
||||
local dict_speed = G_reader_settings:readSetting("highlight_non_touch_factor_dict") or 3
|
||||
local double_spin_widget = DoubleSpinWidget:new{
|
||||
left_text = _("Reader"),
|
||||
left_value = reader_speed,
|
||||
left_min = 0.25,
|
||||
left_max = 5,
|
||||
left_default = 4,
|
||||
left_precision = "%.2f",
|
||||
left_step = 0.25,
|
||||
left_hold_step = 0.05,
|
||||
right_text = _("Dictionary"),
|
||||
right_value = dict_speed,
|
||||
right_min = 0.25,
|
||||
right_max = 5,
|
||||
right_default = 3,
|
||||
right_precision = "%.2f",
|
||||
right_step = 0.25,
|
||||
right_hold_step = 0.05,
|
||||
title_text = _("Crosshairs speed"),
|
||||
info_text = _("Select a decimal value from 0.25 to 5. A smaller value increases the travel distance of the crosshairs per keystroke. Font size and this value are inversely correlated, meaning a smaller font size requires a larger value and vice versa."),
|
||||
callback = function(spin)
|
||||
G_reader_settings:saveSetting("highlight_non_touch_factor", spin.value)
|
||||
callback = function(left_value, right_value)
|
||||
G_reader_settings:saveSetting("highlight_non_touch_factor", left_value)
|
||||
G_reader_settings:saveSetting("highlight_non_touch_factor_dict", right_value)
|
||||
if touchmenu_instance then touchmenu_instance:updateItems() end
|
||||
end
|
||||
}
|
||||
UIManager:show(spin_widget)
|
||||
UIManager:show(double_spin_widget)
|
||||
end,
|
||||
})
|
||||
table.insert(menu_items.long_press.sub_item_table, {
|
||||
|
||||
@@ -53,6 +53,7 @@ local DictQuickLookup = InputContainer:extend{
|
||||
dict_index = 1,
|
||||
width = nil,
|
||||
height = nil,
|
||||
nt_text_selector_indicator = nil, -- crosshairs for text selection on non-touch devices
|
||||
-- sboxes containing highlighted text, quick lookup window tries to not hide the word
|
||||
word_boxes = nil,
|
||||
|
||||
@@ -103,25 +104,12 @@ function DictQuickLookup:init()
|
||||
font_size_alt = 8
|
||||
end
|
||||
self.image_alt_face = Font:getFace("cfont", font_size_alt)
|
||||
if Device:hasKeys() then
|
||||
self.key_events.ReadPrevResult = { { Input.group.PgBack } }
|
||||
self.key_events.ReadNextResult = { { Input.group.PgFwd } }
|
||||
self.key_events.Close = { { Input.group.Back } }
|
||||
self.key_events.MenuKeyPress = { { "Menu" } }
|
||||
if Device:hasKeyboard() then
|
||||
self.key_events.ChangeToPrevDict = { { "Shift", "Left" } }
|
||||
self.key_events.ChangeToNextDict = { { "Shift", "Right" } }
|
||||
self.key_events.LookupInputWordClear = { { Input.group.Alphabet }, event = "LookupInputWord" }
|
||||
-- We need to concat here so that the 'del' event press, which propagates to inputText (desirable for previous key_event,
|
||||
-- i.e., LookupInputWordClear) does not remove the last char of self.word
|
||||
self.key_events.LookupInputWord = { { Device:hasSymKey() and "Del" or "Backspace" }, args = self.word .." " }
|
||||
elseif Device:hasScreenKB() then
|
||||
self.key_events.ChangeToPrevDict = { { "ScreenKB", "Left" } }
|
||||
self.key_events.ChangeToNextDict = { { "ScreenKB", "Right" } }
|
||||
-- same case as hasKeyboard
|
||||
self.key_events.LookupInputWord = { { "ScreenKB", "Back" }, args = self.word .." " }
|
||||
end
|
||||
self.allow_key_text_selection = Device:hasDPad()
|
||||
if self.allow_key_text_selection then
|
||||
self.text_selection_started = false
|
||||
self.previous_indicator_pos = nil
|
||||
end
|
||||
self:registerKeyEvents()
|
||||
if Device:isTouchDevice() then
|
||||
local range = Geom:new{
|
||||
x = 0, y = 0,
|
||||
@@ -537,6 +525,17 @@ function DictQuickLookup:init()
|
||||
},
|
||||
},
|
||||
}
|
||||
if self.allow_key_text_selection and Device:hasFewKeys() then
|
||||
table.insert(buttons, 1, {
|
||||
{
|
||||
id = "text_selection",
|
||||
text = _("Text selection"),
|
||||
callback = function()
|
||||
self:onStartTextSelectorIndicator()
|
||||
end,
|
||||
}
|
||||
})
|
||||
end
|
||||
if not self.is_wiki and self.selected_link ~= nil then
|
||||
-- If highlighting some word part of a link (which should be rare),
|
||||
-- add a new first row with a single button to follow this link.
|
||||
@@ -748,7 +747,7 @@ function DictQuickLookup:init()
|
||||
-- NT: add dict_title.left_button and lookup_edit_button to FocusManager.
|
||||
-- It is better to add these two buttons into self.movable, but it is not a FocusManager.
|
||||
-- Only self.button_table is a FocusManager, so the workaround is inserting these two buttons into self.button_table.layout.
|
||||
if Device:hasDPad() then
|
||||
if Device:hasDPad() and not (Device:hasScreenKB() or Device:hasKeyboard()) then
|
||||
table.insert(self.button_table.layout, 1, { self.dict_title.left_button })
|
||||
table.insert(self.button_table.layout, 2, { lookup_edit_button })
|
||||
-- Refocus on the updated layout
|
||||
@@ -759,6 +758,42 @@ function DictQuickLookup:init()
|
||||
table.insert(DictQuickLookup.window_list, self)
|
||||
end
|
||||
|
||||
function DictQuickLookup:registerKeyEvents()
|
||||
if Device:hasKeys() then
|
||||
self.key_events.ReadPrevResult = { { Input.group.PgBack } }
|
||||
self.key_events.ReadNextResult = { { Input.group.PgFwd } }
|
||||
self.key_events.Close = { { Input.group.Back } }
|
||||
self.key_events.MenuKeyPress = { { "Menu" } }
|
||||
if Device:hasScreenKB() or Device:hasKeyboard() then
|
||||
local modifier = Device:hasScreenKB() and "ScreenKB" or "Shift"
|
||||
self.key_events.ChangeToPrevDict = { { modifier, Input.group.PgBack } }
|
||||
self.key_events.ChangeToNextDict = { { modifier, Input.group.PgFwd } }
|
||||
self.key_events.StartOrUpTextSelectorIndicator = { { modifier, "Up" }, event = "StartOrMoveTextSelectorIndicator", args = { 0, -1, true } }
|
||||
self.key_events.StartOrDownTextSelectorIndicator = { { modifier, "Down" }, event = "StartOrMoveTextSelectorIndicator", args = { 0, 1, true } }
|
||||
self.key_events.FastLeftTextSelectorIndicator = { { modifier, "Left" }, event = "MoveTextSelectorIndicator", args = { -1, 0, true } }
|
||||
self.key_events.FastRightTextSelectorIndicator = { { modifier, "Right" }, event = "MoveTextSelectorIndicator", args = { 1, 0, true } }
|
||||
if Device:hasKeyboard() then
|
||||
self.key_events.LookupInputWordClear = { { Input.group.Alphabet }, event = "LookupInputWord" }
|
||||
-- We need to concat here so that the 'del' event press, which propagates to inputText (desirable for previous key_event,
|
||||
-- i.e., LookupInputWordClear) does not remove the last char of self.word
|
||||
self.key_events.LookupInputWord = { { Device:hasSymKey() and "Del" or "Backspace" }, args = self.word .." " }
|
||||
else
|
||||
-- same case as hasKeyboard
|
||||
self.key_events.LookupInputWord = { { "ScreenKB", "Back" }, args = self.word .." " }
|
||||
end
|
||||
end
|
||||
if Device:hasDPad() then
|
||||
self.key_events.TextSelectorPress = { { "Press" } }
|
||||
self.key_events.UpTextSelectorIndicator = { { "Up" }, event = "MoveTextSelectorIndicator", args = { 0, -1 } }
|
||||
self.key_events.DownTextSelectorIndicator = { { "Down" }, event = "MoveTextSelectorIndicator", args = { 0, 1 } }
|
||||
self.key_events.RightTextSelectorIndicator = { { "Right" }, event = "MoveTextSelectorIndicator", args = { 1, 0 } }
|
||||
if not Device:hasFewKeys() then
|
||||
self.key_events.LeftTextSelectorIndicator = { { "Left" }, event = "MoveTextSelectorIndicator", args = { -1, 0 } }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Whether currently DictQuickLookup is working without a document.
|
||||
function DictQuickLookup:isDocless()
|
||||
return self.ui == nil or self.ui.highlight == nil
|
||||
@@ -832,6 +867,18 @@ function DictQuickLookup:_instantiateScrollWidget()
|
||||
html_link_tapped_callback = function(link)
|
||||
self.html_dictionary_link_tapped_callback(self.dictionary, link)
|
||||
end,
|
||||
-- We need to override the widget's paintTo method to draw our indicator
|
||||
paintTo = self.allow_key_text_selection and function(widget, bb, x, y)
|
||||
-- Call original paintTo from ScrollHtmlWidget
|
||||
ScrollHtmlWidget.paintTo(widget, bb, x, y)
|
||||
-- Draw our indicator on top if we have one
|
||||
if self.nt_text_selector_indicator then
|
||||
local rect = self.nt_text_selector_indicator
|
||||
-- Draw indicator - use crosshairs style
|
||||
bb:paintRect(rect.x + x, rect.y + y + rect.h/2 - 1, rect.w, 2, Blitbuffer.COLOR_BLACK)
|
||||
bb:paintRect(rect.x + x + rect.w/2 - 1, rect.y + y, 2, rect.h, Blitbuffer.COLOR_BLACK)
|
||||
end
|
||||
end or nil,
|
||||
}
|
||||
self.text_widget = self.shw_widget
|
||||
else
|
||||
@@ -848,6 +895,18 @@ function DictQuickLookup:_instantiateScrollWidget()
|
||||
image_alt_face = self.image_alt_face,
|
||||
images = self.images,
|
||||
highlight_text_selection = true,
|
||||
-- We need to override the widget's paintTo method to draw our indicator
|
||||
paintTo = self.allow_key_text_selection and function(widget, bb, x, y)
|
||||
-- Call original paintTo from ScrollTextWidget
|
||||
ScrollTextWidget.paintTo(widget, bb, x, y)
|
||||
-- Draw our indicator on top if we have one
|
||||
if self.nt_text_selector_indicator then
|
||||
local rect = self.nt_text_selector_indicator
|
||||
-- Draw indicator - use crosshairs style
|
||||
bb:paintRect(rect.x + x, rect.y + y + rect.h/2 - 1, rect.w, 2, Blitbuffer.COLOR_BLACK)
|
||||
bb:paintRect(rect.x + x + rect.w/2 - 1, rect.y + y, 2, rect.h, Blitbuffer.COLOR_BLACK)
|
||||
end
|
||||
end or nil,
|
||||
}
|
||||
self.text_widget = self.stw_widget
|
||||
end
|
||||
@@ -1155,6 +1214,11 @@ function DictQuickLookup:onTap(arg, ges_ev)
|
||||
end
|
||||
|
||||
function DictQuickLookup:onClose(no_clear)
|
||||
if self.allow_key_text_selection and self.nt_text_selector_indicator then
|
||||
-- If we're in text selection mode, stop it
|
||||
self:onStopTextSelectorIndicator(true)
|
||||
return true
|
||||
end
|
||||
for menu, _ in pairs(self.menu_opened) do
|
||||
UIManager:close(menu)
|
||||
end
|
||||
@@ -1622,4 +1686,212 @@ function DictQuickLookup:clearDictionaryHighlight()
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
This function initializes and displays a text selection indicator in the dictionary quick lookup widget.
|
||||
1. Suspends focus management and key events in the button table during text selection
|
||||
2. Saves and clears the current focus position (FocusManager)
|
||||
3. Creates the indicator and updates the UI to show it on-screen
|
||||
@return boolean Returns true if the indicator was successfully started, false otherwise
|
||||
]]
|
||||
function DictQuickLookup:onStartTextSelectorIndicator()
|
||||
if not self.definition_widget then return false end -- not yet set up
|
||||
if self.nt_text_selector_indicator then return false end -- already started
|
||||
-- Suspend focus management from button_table instance to prevent the d-pad
|
||||
-- and press keys from moving focus during text selection.
|
||||
self.button_table.movement_allowed = { x = false, y = false }
|
||||
-- Also, temporarily disable key_events during text selection.
|
||||
self.button_table.key_events_enabled = false
|
||||
-- Save current focused-item position before un-focusing it.
|
||||
self._save_focused_item = nil
|
||||
if self.button_table:getFocusItem() then
|
||||
self._save_focused_item = {
|
||||
x = self.button_table.selected.x,
|
||||
y = self.button_table.selected.y
|
||||
}
|
||||
-- it's complicated, but we need two rounds of refocusing in order to clear up the existing focus
|
||||
local FocusManager = require("ui/widget/focusmanager")
|
||||
self.button_table:moveFocusTo(1, 1)
|
||||
self.button_table:moveFocusTo(1, 1, FocusManager.NOT_FOCUS)
|
||||
end
|
||||
-- Create rect with coordinates relative to the content area
|
||||
local rect = self._previous_indicator_pos
|
||||
if not rect then
|
||||
rect = Geom:new()
|
||||
rect.x = math.floor((self.content_width - rect.w) / 2)
|
||||
rect.y = math.floor((self.definition_height - rect.h) / 2)
|
||||
rect.w = Size.item.height_default
|
||||
rect.h = rect.w
|
||||
end
|
||||
self.nt_text_selector_indicator = rect
|
||||
-- Mark the entire definition widget area as dirty to ensure the indicator is drawn
|
||||
UIManager:setDirty(self, function() return "ui", self.definition_widget.dimen end)
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
Stops the text selector indicator and restores normal UI behavior.
|
||||
@param need_clear_selection boolean Whether to clear dictionary highlights after stopping selector
|
||||
@return boolean Returns true if indicator was stopped, false if no indicator existed
|
||||
]]
|
||||
function DictQuickLookup:onStopTextSelectorIndicator(need_clear_selection)
|
||||
if not self.nt_text_selector_indicator then return false end
|
||||
-- resume focus manager's normal operation
|
||||
self.button_table.movement_allowed = { x = true, y = true }
|
||||
-- and re-enable key_events
|
||||
self.button_table.key_events_enabled = true
|
||||
-- Restore previous focus if it was saved
|
||||
if self._save_focused_item then
|
||||
self.button_table:moveFocusTo(self._save_focused_item.x, self._save_focused_item.y)
|
||||
self._save_focused_item = nil
|
||||
end
|
||||
local rect = self.nt_text_selector_indicator
|
||||
self._previous_indicator_pos = rect
|
||||
self._text_selection_started = false
|
||||
self.nt_text_selector_indicator = nil
|
||||
if self._hold_duration then self._hold_duration = nil end
|
||||
-- Mark definition widget area as dirty for clean re-draw
|
||||
UIManager:setDirty(self, function() return "ui", self.definition_widget.dimen end)
|
||||
if need_clear_selection then self:clearDictionaryHighlight() end
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
This function controls the positioning and movement of the text selection indicator,
|
||||
including both normal and quick movement modes. It ensures the indicator stays within
|
||||
the boundaries of the content area and updates the display accordingly.
|
||||
@param args {table} Array containing movement parameters:
|
||||
- dx {number} Horizontal movement delta
|
||||
- dy {number} Vertical movement delta
|
||||
- quick_move {boolean} Whether to use quick movement mode
|
||||
@return {boolean} Returns true if movement was handled, false if text widget or
|
||||
indicator is not available
|
||||
]]
|
||||
function DictQuickLookup:onMoveTextSelectorIndicator(args)
|
||||
if not (self.text_widget and self.nt_text_selector_indicator) then return false end
|
||||
local dx, dy, quick_move = unpack(args)
|
||||
local move_distance = Size.item.height_default / (G_reader_settings:readSetting("highlight_non_touch_factor_dict") or 3)
|
||||
local rect = self.nt_text_selector_indicator:copy()
|
||||
local quick_move_distance_dx = self.content_width * (1/4)
|
||||
local quick_move_distance_dy = self.definition_height * (1/4)
|
||||
if quick_move then
|
||||
rect.x = rect.x + quick_move_distance_dx * dx
|
||||
rect.y = rect.y + quick_move_distance_dy * dy
|
||||
else
|
||||
rect.x = rect.x + move_distance * dx
|
||||
rect.y = rect.y + move_distance * dy
|
||||
end
|
||||
-- Ensure the indicator stays within the content area.
|
||||
if rect.x < 0 then rect.x = 0 end
|
||||
if rect.x + rect.w > self.content_width then
|
||||
if Device:hasFewKeys() then
|
||||
rect.x = 0 -- wrap around to beginning when reaching end
|
||||
else
|
||||
rect.x = self.content_width - rect.w
|
||||
end
|
||||
end
|
||||
if rect.y < 0 then rect.y = 0 end
|
||||
if rect.y + rect.h > self.definition_height then
|
||||
rect.y = self.definition_height - rect.h
|
||||
end
|
||||
-- Update widget state
|
||||
self.nt_text_selector_indicator = rect
|
||||
if self._text_selection_started then
|
||||
local selection_widget = self:_getSelectionWidget(self)
|
||||
if selection_widget then
|
||||
selection_widget:onHoldPanText(nil, self:_createTextSelectionGesture("hold_pan"))
|
||||
end
|
||||
end
|
||||
-- mark widget dirty to ensure the paintTo method that draws the crosshairs is called
|
||||
UIManager:setDirty(self, function() return "ui", self.definition_widget.dimen end)
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
@details This function manages the text selection process and subsequent actions:
|
||||
- Initiates text selection on first press
|
||||
- On second press (when selection is complete):
|
||||
* Processes the selection
|
||||
* Handles Wikipedia/Dictionary lookup
|
||||
]]
|
||||
function DictQuickLookup:onTextSelectorPress()
|
||||
if not self.nt_text_selector_indicator then return false end
|
||||
local selection_widget = self:_getSelectionWidget(self)
|
||||
if not selection_widget then self:onStopTextSelectorIndicator() return end
|
||||
if not self._text_selection_started then
|
||||
-- start text selection on first press
|
||||
self._text_selection_started = true
|
||||
-- we'll time the hold duration to allow switching from wiki to dict
|
||||
self._hold_duration = time.now() -- on your marks, get set, go!
|
||||
selection_widget:onHoldStartText(nil, self:_createTextSelectionGesture("hold"))
|
||||
-- center indicator on selected text if available
|
||||
if selection_widget.highlight_rects and #selection_widget.highlight_rects > 0 then
|
||||
local highlight = selection_widget.highlight_rects[1]
|
||||
local indicator = self.nt_text_selector_indicator
|
||||
indicator.x = highlight.x + (highlight.w/2) - (indicator.w/2)
|
||||
indicator.y = highlight.y + (highlight.h/2) - (indicator.h/2)
|
||||
UIManager:setDirty(self, function() return "ui", self.definition_widget.dimen end)
|
||||
end
|
||||
return true
|
||||
end
|
||||
-- second press,
|
||||
-- process the hold release event which finalizes text selection
|
||||
selection_widget:onHoldReleaseText(nil, self:_createTextSelectionGesture("hold_release"))
|
||||
local hold_duration = time.to_s(time.since(self._hold_duration))
|
||||
local selected_text
|
||||
-- both text_widget and htmlbox_widget handle text parsing a bit differently, ¯\_(ツ)_/¯
|
||||
if self.is_html then
|
||||
-- For HtmlBoxWidget, highlight_text should contain the complete text selection.
|
||||
selected_text = selection_widget.highlight_text
|
||||
else
|
||||
-- For TextBoxWidget, extract the selected text using the indices.
|
||||
selected_text = selection_widget.text:sub(
|
||||
selection_widget.highlight_start_idx,
|
||||
selection_widget.highlight_end_idx
|
||||
)
|
||||
end
|
||||
if selected_text then
|
||||
local lookup_wikipedia = self.is_wiki
|
||||
if lookup_wikipedia and hold_duration > 5 then
|
||||
-- allow switching domain with a long hold (> 5 secs)
|
||||
lookup_wikipedia = false
|
||||
end
|
||||
local new_dict_close_callback = function() self:clearDictionaryHighlight() end
|
||||
if lookup_wikipedia then
|
||||
self:lookupWikipedia(false, selected_text, nil, nil, new_dict_close_callback)
|
||||
else
|
||||
self.ui:handleEvent(Event:new("LookupWord", selected_text, nil, nil, nil, nil, new_dict_close_callback))
|
||||
end
|
||||
end
|
||||
self:onStopTextSelectorIndicator()
|
||||
return true
|
||||
end
|
||||
|
||||
function DictQuickLookup:onStartOrMoveTextSelectorIndicator(args)
|
||||
if not self.nt_text_selector_indicator then
|
||||
self:onStartTextSelectorIndicator()
|
||||
else
|
||||
self:onMoveTextSelectorIndicator(args)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- helper function to get the actual widget that handles text selection
|
||||
function DictQuickLookup:_getSelectionWidget(instance)
|
||||
return instance.is_html and instance.text_widget.htmlbox_widget or instance.text_widget.text_widget
|
||||
end
|
||||
|
||||
function DictQuickLookup:_createTextSelectionGesture(gesture)
|
||||
local point = self.nt_text_selector_indicator:copy()
|
||||
-- Add the definition_widget's absolute position to get correct screen coordinates
|
||||
point.x = point.x + point.w / 2 + self.definition_widget.dimen.x
|
||||
point.y = point.y + point.h / 2 + self.definition_widget.dimen.y
|
||||
point.w = 0
|
||||
point.h = 0
|
||||
return {
|
||||
ges = gesture,
|
||||
pos = point,
|
||||
time = time.realtime(),
|
||||
}
|
||||
end
|
||||
|
||||
return DictQuickLookup
|
||||
|
||||
@@ -30,6 +30,7 @@ local FocusManager = InputContainer:extend{
|
||||
selected = nil, -- defaults to x=1, y=1
|
||||
layout = nil, -- mandatory
|
||||
movement_allowed = { x = true, y = true },
|
||||
key_events_enabled = true,
|
||||
}
|
||||
|
||||
-- Only build the default mappings once on initialization, or when an external keyboard is (dis-)/connected.
|
||||
@@ -517,4 +518,12 @@ function FocusManager:refocusWidget(nextTick, focus_flags)
|
||||
end
|
||||
end
|
||||
|
||||
function FocusManager:onKeyPress(key)
|
||||
-- Add check for key_events_enabled
|
||||
if not self.key_events_enabled then
|
||||
return false
|
||||
end
|
||||
return InputContainer.onKeyPress(self, key)
|
||||
end
|
||||
|
||||
return FocusManager
|
||||
|
||||
Reference in New Issue
Block a user