mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
TextViewer: pin page (#14668)
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user