mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
DictQuickLookup: add button to show list of results
Add a left button to the title bar to show the list of results as a popup. Dictionary: tap or long-press on that button give different view of the results. Wikipedia: request 30 results instead of 20, so we can show 15, 10 or 6 of them per page of that popup.
This commit is contained in:
@@ -488,7 +488,7 @@ function ReaderWikipedia:lookupWikipedia(word, is_sane, box, get_fullpage, force
|
||||
pages = sorted_pages
|
||||
end
|
||||
for pageid, page in pairs(pages) do
|
||||
local definition = page.extract or no_result_text
|
||||
local definition = page.extract or (page.length and _("No introduction.")) or no_result_text
|
||||
if page.length then
|
||||
-- we get 'length' only for intro results
|
||||
-- let's append it to definition so we know
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local BD = require("ui/bidi")
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local ButtonTable = require("ui/widget/buttontable")
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local Device = require("device")
|
||||
@@ -216,7 +217,22 @@ function DictQuickLookup:init()
|
||||
align = self.is_wiki and "center" or "left",
|
||||
show_parent = self,
|
||||
lang = self.lang_out,
|
||||
left_icon = "appbar.menu",
|
||||
left_icon_tap_callback = function()
|
||||
if self.is_wiki then
|
||||
self:showWikiResultsMenu()
|
||||
else
|
||||
self:showResultsMenu()
|
||||
end
|
||||
end,
|
||||
left_icon_hold_callback = not self.is_wiki and function() self:showResultsAltMenu() end or nil,
|
||||
}
|
||||
-- Scrollable offsets of the various showResults* menus and submenus,
|
||||
-- so we can reopen them in the same state they were when closed.
|
||||
self.menu_scrolled_offsets = {}
|
||||
-- We'll also need to close any opened such menu when closing this DictQuickLookup
|
||||
-- (needed if closing all DictQuickLookups via long-press on Close on the top one)
|
||||
self.menu_opened = {}
|
||||
|
||||
-- This padding and the resulting width apply to the content
|
||||
-- below the title: lookup word and definition
|
||||
@@ -1120,6 +1136,11 @@ function DictQuickLookup:onTap(arg, ges_ev)
|
||||
end
|
||||
|
||||
function DictQuickLookup:onClose(no_clear)
|
||||
for menu, _ in pairs(self.menu_opened) do
|
||||
UIManager:close(menu)
|
||||
end
|
||||
self.menu_opened = {}
|
||||
|
||||
UIManager:close(self)
|
||||
|
||||
if self.update_wiki_languages_on_close then
|
||||
@@ -1318,4 +1339,247 @@ function DictQuickLookup:lookupWikipedia(get_fullpage, word, is_sane, lang)
|
||||
self.ui:handleEvent(Event:new("LookupWikipedia", word, is_sane, self.word_boxes, get_fullpage, lang))
|
||||
end
|
||||
|
||||
function DictQuickLookup:showResultsMenu()
|
||||
-- Show one row: "| word | dict |" for each result
|
||||
local width = math.floor(self.width * 0.75)
|
||||
local right_width = math.floor(width * 0.5)
|
||||
local font_size = 18
|
||||
local button_dialog
|
||||
local buttons = {}
|
||||
for idx, result in ipairs(self.results) do
|
||||
-- Show in bold the currently displayed result
|
||||
local bold = idx == self.dict_index
|
||||
local row = {
|
||||
{
|
||||
text = result.word,
|
||||
lang = result.ifo_lang and result.ifo_lang.lang_in or nil,
|
||||
font_size = font_size,
|
||||
font_bold = bold,
|
||||
align = "left",
|
||||
callback = function()
|
||||
self.menu_scrolled_offsets["main"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(idx)
|
||||
end,
|
||||
hold_callback = function()
|
||||
-- Allow doing another lookup with this result word
|
||||
self.ui:handleEvent(Event:new("LookupWord", result.word))
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = result.dict,
|
||||
lang = result.ifo_lang and result.ifo_lang.lang_out or nil,
|
||||
font_size = font_size,
|
||||
font_bold = bold,
|
||||
width = right_width,
|
||||
callback = function()
|
||||
self.menu_scrolled_offsets["main"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(idx)
|
||||
end,
|
||||
},
|
||||
}
|
||||
table.insert(buttons, row)
|
||||
end
|
||||
button_dialog = ButtonDialog:new{
|
||||
width = width,
|
||||
-- We don't provide shrink_unneeded_width=true as it's ugly with small words
|
||||
buttons = buttons,
|
||||
anchor = function()
|
||||
return self.dict_title.left_button.image.dimen, true -- pop down
|
||||
end,
|
||||
tap_close_callback = function()
|
||||
self.menu_scrolled_offsets["main"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
end
|
||||
}
|
||||
button_dialog:setScrolledOffset(self.menu_scrolled_offsets["main"])
|
||||
self.menu_opened[button_dialog] = true
|
||||
UIManager:show(button_dialog)
|
||||
end
|
||||
|
||||
function DictQuickLookup:showResultsAltMenu()
|
||||
-- Alternative listing with long-press:
|
||||
-- Show one row: "| dict | word or N results |" for each dictionary returning results
|
||||
local dicts = {}
|
||||
local dict_results = {}
|
||||
for idx, result in ipairs(self.results) do
|
||||
local dict = result.dict
|
||||
if not dict_results[dict] then
|
||||
dict_results[dict] = { idx }
|
||||
table.insert(dicts, dict)
|
||||
else
|
||||
table.insert(dict_results[dict], idx)
|
||||
end
|
||||
end
|
||||
local max_width = math.floor(self.width * 0.75)
|
||||
local right_width = math.floor(max_width * 0.25)
|
||||
local font_size = 18
|
||||
local button_dialog
|
||||
local buttons = {}
|
||||
for dictnum, dict in ipairs(dicts) do
|
||||
local results = dict_results[dict]
|
||||
local first_result = self.results[results[1]]
|
||||
-- Show in bold only the currently displayed result's dict
|
||||
local bold = util.arrayContains(results, self.dict_index)
|
||||
local row = {{
|
||||
text = dict,
|
||||
lang = first_result.ifo_lang and first_result.ifo_lang.lang_out or nil,
|
||||
font_size = font_size,
|
||||
font_bold = bold,
|
||||
align = "left",
|
||||
callback = function()
|
||||
self.menu_scrolled_offsets["alt"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(results[1])
|
||||
end,
|
||||
}}
|
||||
-- Right button
|
||||
local button_id = "button"..dictnum
|
||||
local text, lang, avoid_text_truncation, is_single_result, hold_callback
|
||||
if #results == 1 then
|
||||
-- Show the headword, possibly truncated (otherwise, long words
|
||||
-- would get displayed in a really small font size).
|
||||
-- If truncated, we'll show it full in a popup
|
||||
text = first_result.word
|
||||
lang = first_result.ifo_lang and first_result.ifo_lang.lang_in or nil
|
||||
avoid_text_truncation = false
|
||||
is_single_result = true
|
||||
hold_callback = function()
|
||||
-- Allow doing another lookup with this result word
|
||||
self.ui:handleEvent(Event:new("LookupWord", first_result.word))
|
||||
end
|
||||
else
|
||||
text = T(_("%1 results"), #results)
|
||||
end
|
||||
local callback = function()
|
||||
local source_button = button_dialog:getButtonById(button_id)
|
||||
if is_single_result and not source_button.label_widget:isTruncated() then
|
||||
-- Not truncated: jump directly to the result
|
||||
self.menu_scrolled_offsets["alt"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(results[1])
|
||||
return
|
||||
end
|
||||
local button_dialog2
|
||||
local buttons2 = {}
|
||||
local lang2 = first_result.ifo_lang and first_result.ifo_lang.lang_in or nil -- same for all results
|
||||
for res=1, #results do
|
||||
table.insert(buttons2, {{
|
||||
text = self.results[results[res]].word,
|
||||
lang = lang2,
|
||||
font_size = font_size,
|
||||
font_bold = results[res] == self.dict_index,
|
||||
callback = function()
|
||||
self.menu_scrolled_offsets["alt_sub"..dictnum] = button_dialog2:getScrolledOffset()
|
||||
self.menu_opened[button_dialog2] = nil
|
||||
UIManager:close(button_dialog2)
|
||||
self.menu_scrolled_offsets["alt"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(results[res])
|
||||
end,
|
||||
hold_callback = function()
|
||||
-- Allow doing another lookup with this result word
|
||||
self.ui:handleEvent(Event:new("LookupWord", self.results[results[res]].word))
|
||||
end,
|
||||
}})
|
||||
end
|
||||
button_dialog2 = ButtonDialog:new{
|
||||
width = right_width*2, -- larger, to have room for long words
|
||||
buttons = buttons2,
|
||||
anchor = function()
|
||||
return source_button.dimen, true -- pop down
|
||||
end,
|
||||
tap_close_callback = function()
|
||||
self.menu_scrolled_offsets["alt_sub"..dictnum] = button_dialog2:getScrolledOffset()
|
||||
self.menu_opened[button_dialog2] = nil
|
||||
end
|
||||
}
|
||||
button_dialog2:setScrolledOffset(self.menu_scrolled_offsets["alt_sub"..dictnum])
|
||||
self.menu_opened[button_dialog2] = true
|
||||
UIManager:show(button_dialog2)
|
||||
end
|
||||
table.insert(row, {
|
||||
text = text,
|
||||
lang = lang,
|
||||
avoid_text_truncation = avoid_text_truncation,
|
||||
font_size = font_size,
|
||||
font_bold = bold,
|
||||
width = right_width,
|
||||
callback = callback,
|
||||
hold_callback = hold_callback,
|
||||
id = button_id,
|
||||
})
|
||||
table.insert(buttons, row)
|
||||
end
|
||||
button_dialog = ButtonDialog:new{
|
||||
width = max_width,
|
||||
shrink_unneeded_width = true,
|
||||
buttons = buttons,
|
||||
anchor = function()
|
||||
return self.dict_title.left_button.image.dimen, true -- pop down
|
||||
end,
|
||||
tap_close_callback = function()
|
||||
self.menu_scrolled_offsets["alt"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
end
|
||||
}
|
||||
button_dialog:setScrolledOffset(self.menu_scrolled_offsets["alt"])
|
||||
self.menu_opened[button_dialog] = true
|
||||
UIManager:show(button_dialog)
|
||||
end
|
||||
|
||||
function DictQuickLookup:showWikiResultsMenu()
|
||||
-- Show one row with each result's article title
|
||||
local max_width = math.floor(self.width * 0.75)
|
||||
local font_size = 18
|
||||
local button_dialog
|
||||
local buttons = {}
|
||||
for idx, result in ipairs(self.results) do
|
||||
local bold = idx == self.dict_index
|
||||
local row = {{
|
||||
text = result.word,
|
||||
lang = result.lang,
|
||||
font_size = font_size,
|
||||
font_bold = bold,
|
||||
align = "left",
|
||||
callback = function()
|
||||
self.menu_scrolled_offsets["wiki"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
UIManager:close(button_dialog)
|
||||
self:changeDictionary(idx)
|
||||
end,
|
||||
hold_callback = function()
|
||||
-- Allow doing another lookup with this result title
|
||||
self:lookupWikipedia(false, result.word)
|
||||
end,
|
||||
}}
|
||||
table.insert(buttons, row)
|
||||
end
|
||||
button_dialog = ButtonDialog:new{
|
||||
width = max_width,
|
||||
shrink_unneeded_width = true,
|
||||
buttons = buttons,
|
||||
-- We requested 30 results, so we will probably be scrolling.
|
||||
-- If we do, ensure we use these values (they will all make full pages
|
||||
-- if we get 30 results), depending on what the screen height allows.
|
||||
rows_per_page = { 15, 10, 6 },
|
||||
anchor = function()
|
||||
return self.dict_title.left_button.image.dimen, true -- pop down
|
||||
end,
|
||||
tap_close_callback = function()
|
||||
self.menu_scrolled_offsets["wiki"] = button_dialog:getScrolledOffset()
|
||||
self.menu_opened[button_dialog] = nil
|
||||
end
|
||||
}
|
||||
button_dialog:setScrolledOffset(self.menu_scrolled_offsets["wiki"])
|
||||
self.menu_opened[button_dialog] = true
|
||||
UIManager:show(button_dialog)
|
||||
end
|
||||
|
||||
return DictQuickLookup
|
||||
|
||||
@@ -30,7 +30,7 @@ local Wikipedia = {
|
||||
generator = "search",
|
||||
gsrnamespace = "0",
|
||||
-- gsrsearch = nil, -- text to lookup, will be added below
|
||||
gsrlimit = 20, -- max nb of results to get
|
||||
gsrlimit = 30, -- max nb of results to get
|
||||
exlimit = "max",
|
||||
prop = "extracts|info|pageimages", -- 'extracts' to get text, 'info' to get full page length
|
||||
format = "json",
|
||||
|
||||
Reference in New Issue
Block a user