TextViewer: pin page (#14668)

This commit is contained in:
hius07
2025-12-09 07:43:23 +02:00
committed by GitHub
parent 757f8f300a
commit 9dc068b50d
2 changed files with 128 additions and 17 deletions

View File

@@ -1225,6 +1225,20 @@ function TextBoxWidget:getCharPos()
return self.charpos, self.virtual_line_num, self.current_line_num
end
function TextBoxWidget:getCharPageTopLineNumber(charpos)
-- returns top line number of the page containing charpos
local ln = 1
while true do
local lend = ln + self.lines_per_page - 1
if lend >= #self.vertical_string_list -- last page
or self.vertical_string_list[lend + 1].offset > charpos
then
return ln
end
ln = ln + self.lines_per_page
end
end
function TextBoxWidget:getSize()
-- Make sure we actually have a BB, in case we're recycling an instance... (c.f., #8241)
if not self._bb then
@@ -1887,21 +1901,10 @@ function TextBoxWidget:scrollViewToCharPos()
end
-- and adjust if cursor is out of view
self:moveCursorToCharPos(self.charpos)
return
else
-- Otherwise, find the "hard" page containing charpos
self.virtual_line_num = self:getCharPageTopLineNumber(self.charpos)
end
-- Otherwise, find the "hard" page containing charpos
local ln = 1
while true do
local lend = ln + self.lines_per_page - 1
if lend >= #self.vertical_string_list then
break -- last page
end
if self.vertical_string_list[lend+1].offset >= self.charpos then
break
end
ln = ln + self.lines_per_page
end
self.virtual_line_num = ln
end
function TextBoxWidget:moveCursorLeft()

View File

@@ -39,6 +39,8 @@ local Screen = Device.screen
local TextViewer = InputContainer:extend{
title = nil,
text = nil,
file = nil, -- filepath if file content is displayed, triggers showing Pin buttons
pinned_page = nil, -- position of the page upper left char
charlist = nil, -- internal
width = nil,
height = nil,
@@ -102,6 +104,10 @@ function TextViewer:init(reinit)
self.monospace_font = text_settings.monospace_font
self.text_font_size = text_settings.font_size
self.justified = text_settings.justified
if self.file then
local pinned_pages = G_reader_settings:readSetting("textviewer_pinned_pages")
self.pinned_page = pinned_pages and pinned_pages[self.file]
end
end
local text_font_face = self.monospace_font and "smallinfont" or "x_smallinfofont"
@@ -172,7 +178,7 @@ function TextViewer:init(reinit)
width = self.width,
align = "left",
with_bottom_line = true,
title = self.title,
title = self.title or self.file,
title_face = self.title_face,
title_multilines = self.title_multilines,
title_shrink_font_to_fit = self.title_shrink_font_to_fit,
@@ -214,6 +220,106 @@ function TextViewer:init(reinit)
end
-- buttons
local pin_buttons = self.file and
{
{
text = _("Pin current page"),
callback = function()
if self.pinned_page == nil then
local pin_button = self.button_table:getButtonById("go_to_pin")
pin_button:enable()
pin_button:refresh()
end
self.pinned_page = self.scroll_text_w.text_widget:getCharPosAtXY(0, 0)
local pinned_pages = G_reader_settings:readSetting("textviewer_pinned_pages", {})
pinned_pages[self.file] = self.pinned_page
UIManager:show(Notification:new{ text = _("Page pinned") })
end,
hold_callback = function()
local pinned_pages = G_reader_settings:readSetting("textviewer_pinned_pages")
if pinned_pages == nil then return end
local dialog
local buttons = {
{{
text = _("Remove pinned pages of all files"),
callback = function()
UIManager:close(dialog)
if self.pinned_page then
self.pinned_page = nil
local pin_button = self.button_table:getButtonById("go_to_pin")
pin_button:disable()
pin_button:refresh()
end
G_reader_settings:delSetting("textviewer_pinned_pages")
UIManager:show(Notification:new{ text = _("All pinned pages removed") })
end,
}},
{{
text = _("Remove pinned pages of deleted files"),
callback = function()
UIManager:close(dialog)
for file in pairs(pinned_pages) do
if lfs.attributes(file, "mode") ~= "file" then
pinned_pages[file] = nil
end
end
if next(pinned_pages) == nil then
G_reader_settings:delSetting("textviewer_pinned_pages")
end
UIManager:show(Notification:new{ text = _("Pinned pages removed") })
end,
}},
{}, -- separator
{
{
text = _("Cancel"),
callback = function()
UIManager:close(dialog)
end,
},
{
text = _("Remove"),
enabled = self.pinned_page ~= nil,
callback = function()
UIManager:close(dialog)
self.pinned_page = nil
local pin_button = self.button_table:getButtonById("go_to_pin")
pin_button:disable()
pin_button:refresh()
pinned_pages[self.file] = nil
if next(pinned_pages) == nil then
G_reader_settings:delSetting("textviewer_pinned_pages")
end
UIManager:show(Notification:new{ text = _("Pinned page removed") })
end,
},
},
}
dialog = ButtonDialog:new{
title = _("Remove pinned page?"),
title_align = "center",
buttons = buttons,
}
UIManager:show(dialog)
end,
},
{
text = _("Go to pinned page"),
id = "go_to_pin",
enabled_func = function()
return self.pinned_page ~= nil
end,
callback = function()
local new_virtual_line_num = self.scroll_text_w.text_widget:getCharPageTopLineNumber(self.pinned_page)
if self.scroll_text_w.text_widget.virtual_line_num ~= new_virtual_line_num then
self.scroll_text_w.text_widget.virtual_line_num = new_virtual_line_num
self.scroll_text_w.text_widget:free(false)
self.scroll_text_w.text_widget:_updateLayout()
self.scroll_text_w:updateScrollBar(true)
end
end,
},
}
local default_buttons =
{
{
@@ -264,6 +370,9 @@ function TextViewer:init(reinit)
}
local buttons = self.buttons_table or {}
if (self.add_default_buttons and not reinit) or not self.buttons_table then
if self.file then
table.insert(buttons, pin_buttons)
end
table.insert(buttons, default_buttons)
end
self.button_table = ButtonTable:new{
@@ -281,7 +390,6 @@ function TextViewer:init(reinit)
end
local textw_height = self.height - self.titlebar:getHeight() - self.button_table:getSize().h
self.scroll_text_w = ScrollTextWidget:new{
text = self.text,
face = Font:getFace(text_font_face, self.text_font_size),
@@ -683,7 +791,7 @@ function TextViewer.openFile(file)
local file_content = file_handle:read("*all")
file_handle:close()
UIManager:show(TextViewer:new{
title = file_path,
file = file_path,
title_multilines = true,
text = file_content,
text_type = "file_content",