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.
pull/10440/head
poire-z 1 year ago
parent 8c8a032269
commit fc81c7db24

@ -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",

Loading…
Cancel
Save