TextViewer: add dialog to set font size and justify text (#11210)

reviewable/pr11230/r1
hius07 5 months ago committed by GitHub
parent fe02b83b6a
commit f4a5a2b60a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -526,6 +526,7 @@ function ReaderBookmark:onShowBookmark(match_table)
textviewer = TextViewer:new{
title = _("Bookmark details"),
text = bm_view,
text_type = "bookmark",
buttons_table = {
{
{

@ -927,6 +927,7 @@ function ReaderHighlight:showHighlightNoteOrDialog(page, index, bookmark_note)
local textviewer
textviewer = TextViewer:new{
title = _("Note"),
show_menu = false,
text = bookmark_note,
width = math.floor(math.min(self.screen_w, self.screen_h) * 0.8),
height = math.floor(math.max(self.screen_w, self.screen_h) * 0.4),

@ -200,8 +200,7 @@ When the book's language tag is not among our presets, no specific features will
UIManager:show(TextViewer:new{
title = _("Language tags (and hyphenation dictionaries) used since start up"),
text = status_text,
text_font_face = "smallinfont",
justified = false,
text_type = "code",
height = math.floor(Screen:getHeight() * 0.8),
})
end,

@ -686,6 +686,7 @@ function Translator:_showTranslation(text, detailed_view, source_lang, target_la
-- Showing the translation target language in this title may make
-- it quite long and wrapped, taking valuable vertical spacing
text = text_all,
text_type = "lookup",
height = height,
add_default_buttons = true,
buttons_table = buttons_table,

@ -30,7 +30,6 @@ local ViewHtml = {
-- Or additionally show unicode codepoint of each char
{ _("Switch to unicode debug view"), 0xEB5E, true },
},
text_font_face = "smallinfont",
}
-- Main entry point
@ -124,8 +123,7 @@ function ViewHtml:_viewSelectionHTML(document, selected_text, view, with_css_fil
cssviewer = TextViewer:new{
title = css_files[i],
text = css_text or _("Failed getting CSS content"),
text_font_face = self.text_font_face,
justified = false,
text_type = "code",
para_direction_rtl = false,
auto_para_direction = false,
add_default_buttons = true,
@ -138,8 +136,7 @@ function ViewHtml:_viewSelectionHTML(document, selected_text, view, with_css_fil
UIManager:show(TextViewer:new{
title = css_files[i],
text = util.prettifyCSS(css_text),
text_font_face = self.text_font_face,
justified = false,
text_type = "code",
para_direction_rtl = false,
auto_para_direction = false,
})
@ -185,8 +182,7 @@ function ViewHtml:_viewSelectionHTML(document, selected_text, view, with_css_fil
textviewer = TextViewer:new{
title = _("Selection HTML"),
text = html,
text_font_face = self.text_font_face,
justified = false,
text_type = "code",
para_direction_rtl = false,
auto_para_direction = false,
add_default_buttons = true,
@ -420,8 +416,7 @@ function ViewHtml:_showMatchingSelectors(document, ancestors, show_all_ancestors
cssviewer = TextViewer:new{
title = title,
text = css_text or _("No matching rulesets"),
text_font_face = self.text_font_face,
justified = false,
text_type = "code",
para_direction_rtl = false,
auto_para_direction = false,
add_default_buttons = true,
@ -434,8 +429,7 @@ function ViewHtml:_showMatchingSelectors(document, ancestors, show_all_ancestors
UIManager:show(TextViewer:new{
title = title,
text = util.prettifyCSS(css_text),
text_font_face = self.text_font_face,
justified = false,
text_type = "code",
para_direction_rtl = false,
auto_para_direction = false,
})

@ -1201,53 +1201,23 @@ function BookMapWidget:showMenu()
end,
}},
{{
text_func = function(no_size_trick)
-- A bit tricky to update the text in the callback, as this button,
-- being sized by ButtonTable, can't be rebuilt. We will update its
-- text, and we want to be sure it will fit in the initial width,
-- which may be with the checkmark or not.
local text = _("Page browser on tap")
if G_reader_settings:nilOrTrue("book_map_tap_to_page_browser") then
text = text .. " \u{2713}" -- checkmark
else
if not no_size_trick then
-- Initial call, make it wide enough so the checkmark text will fit
text = text .. " \u{2003}" -- wide em space
end
-- Otherwise, keep it small without the checkmark, which will fit
end
return text
text = _("Page browser on tap"),
checked_func = function()
return G_reader_settings:nilOrTrue("book_map_tap_to_page_browser")
end,
id = "tap_to_page_browser",
align = "left",
callback = function()
G_reader_settings:flipNilOrTrue("book_map_tap_to_page_browser")
local b = button_dialog:getButtonById("tap_to_page_browser")
b:setText(b.text_func(true), b.width)
b:refresh()
end,
}},
{{
text_func = function(no_size_trick)
local text = _("Alternative theme")
if G_reader_settings:isTrue("book_map_alt_theme") then
text = text .. " \u{2713}" -- checkmark
else
if not no_size_trick then
-- Initial call, make it wide enough so the checkmark text will fit
text = text .. " \u{2003}" -- wide em space
end
-- Otherwise, keep it small without the checkmark, which will fit
end
return text
text = _("Alternative theme"),
checked_func = function()
return G_reader_settings:isTrue("book_map_alt_theme")
end,
id = "alt_theme",
align = "left",
callback = function()
G_reader_settings:flipTrue("book_map_alt_theme")
local b = button_dialog:getButtonById("alt_theme")
b:setText(b.text_func(true), b.width)
b:refresh()
self.editable_stuff_edited = true -- have this change reflected on any lower bookmap & pagebrowser
self:update()
end,

@ -37,6 +37,8 @@ local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local Button = InputContainer:extend{
text = nil, -- mandatory (unless icon is provided)
text_func = nil,
checked_func = nil, -- checkmark appended to text
checkmark = " \u{2713}",
lang = nil,
icon = nil,
icon_width = Screen:scaleBySize(DGENERIC_ICON_SIZE), -- our icons are square
@ -98,21 +100,33 @@ function Button:init()
-- TextWidget or TextBoxWidget in that height (hopefully no ink will overflow)
local reference_height
if self.text then
local text = self.checked_func == nil and self.text or self:getDisplayText()
local fgcolor = self.enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY
local face = Font:getFace(self.text_font_face, self.text_font_size)
local max_width = self.max_width or self.width
if max_width then
max_width = max_width - outer_pad_width
end
self.label_widget = TextWidget:new{
text = self.text,
text = text,
lang = self.lang,
max_width = max_width,
fgcolor = self.enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY,
fgcolor = fgcolor,
bold = self.text_font_bold,
face = Font:getFace(self.text_font_face, self.text_font_size)
face = face,
}
reference_height = self.label_widget:getSize().h
if not self.label_widget:isTruncated() then
self._min_needed_width = self.label_widget:getSize().w + outer_pad_width
local checkmark_width = 0
if self.checked_func and not self.checked_func() then
local tmp = TextWidget:new{
text = self.checkmark,
face = face,
}
checkmark_width = tmp:getSize().w
tmp:free()
end
self._min_needed_width = self.label_widget:getSize().w + checkmark_width + outer_pad_width
end
self.did_truncation_tweaks = false
if self.avoid_text_truncation and self.label_widget:isTruncated() then
@ -124,7 +138,7 @@ function Button:init()
-- Switch to a 2-lines TextBoxWidget
self.label_widget:free(true)
self.label_widget = TextBoxWidget:new{
text = self.text,
text = text,
lang = self.lang,
line_height = 0,
alignment = self.align,
@ -132,9 +146,9 @@ function Button:init()
height = reference_height,
height_adjust = true,
height_overflow_show_ellipsis = true,
fgcolor = self.enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY,
fgcolor = fgcolor,
bold = self.text_font_bold,
face = Font:getFace(self.text_font_face, new_size)
face = Font:getFace(self.text_font_face, new_size),
}
if not self.label_widget.has_split_inside_word then
break
@ -147,12 +161,12 @@ function Button:init()
end
self.label_widget:free(true)
self.label_widget = TextWidget:new{
text = self.text,
text = text,
lang = self.lang,
max_width = max_width,
fgcolor = self.enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY,
fgcolor = fgcolor,
bold = self.text_font_bold,
face = Font:getFace(self.text_font_face, new_size)
face = Font:getFace(self.text_font_face, new_size),
}
end
end
@ -262,6 +276,10 @@ function Button:setIcon(icon, width)
end
end
function Button:getDisplayText()
return self.checked_func() and self.text .. self.checkmark or self.text
end
function Button:onFocus()
if self.no_focus then return end
self.frame.invert = true
@ -472,6 +490,11 @@ function Button:onTapSelectButton()
UIManager:forceRePaint()
end
end
if self.checked_func then
local text = self:getDisplayText()
self.label_widget:setText(text)
self:refresh()
end
elseif self.tap_input then
self:onInput(self.tap_input)
elseif type(self.tap_input_func) == "function" then

@ -66,6 +66,7 @@ function ButtonTable:init()
local button = Button:new{
text = btn_entry.text,
text_func = btn_entry.text_func,
checked_func = btn_entry.checked_func,
lang = btn_entry.lang,
icon = btn_entry.icon,
icon_width = btn_entry.icon_width,

@ -189,6 +189,7 @@ local function initTouchEvents()
local clipboard_dialog
clipboard_dialog = require("ui/widget/textviewer"):new{
title = _("Clipboard"),
show_menu = false,
text = is_clipboard_empty and _("(empty)") or clipboard_value,
fgcolor = is_clipboard_empty and Blitbuffer.COLOR_DARK_GRAY or Blitbuffer.COLOR_BLACK,
width = math.floor(math.min(Screen:getWidth(), Screen:getHeight()) * 0.8),

@ -891,30 +891,13 @@ function PageBrowserWidget:showMenu()
end,
}},
{{
text_func = function(no_size_trick)
-- A bit tricky to update the text in the callback, as this button,
-- being sized by ButtonTable, can't be rebuilt. We will update its
-- text, and we want to be sure it will fit in the initial width,
-- which may be with the checkmark or not.
local text = _("Preload next/prev thumbnails")
if G_reader_settings:isTrue("page_browser_preload_thumbnails") then
text = text .. " \u{2713}" -- checkmark
else
if not no_size_trick then
-- Initial call, make it wide enough so the checkmark text will fit
text = text .. " \u{2003}" -- wide em space
end
-- Otherwise, keep it small without the checkmark, which will fit
end
return text
text = _("Preload next/prev thumbnails"),
checked_func = function()
return G_reader_settings:isTrue("page_browser_preload_thumbnails")
end,
id = "preload_thumbnails",
align = "left",
callback = function()
G_reader_settings:flipTrue("page_browser_preload_thumbnails")
local b = button_dialog:getButtonById("preload_thumbnails")
b:setText(b.text_func(true), b.width)
b:refresh()
if G_reader_settings:isTrue("page_browser_preload_thumbnails") then
self:preloadNextPrevScreenThumbnails()
end

@ -10,6 +10,7 @@ Displays some text in a scrollable view.
]]
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 CheckButton = require("ui/widget/checkbutton")
@ -47,7 +48,6 @@ local TextViewer = InputContainer:extend{
-- When used to display more technical text (HTML, CSS,
-- application logs...), it's best to reset them to false.
alignment = "left",
justified = nil,
lang = nil,
para_direction_rtl = nil,
auto_para_direction = true,
@ -57,8 +57,11 @@ local TextViewer = InputContainer:extend{
title_multilines = nil, -- see TitleBar for details
title_shrink_font_to_fit = nil, -- see TitleBar for details
text_font_face = nil, -- default "x_smallinfofont"
text_font_size = nil,
show_menu = true, -- titlebar left icon
monospace_font = nil, -- internal
text_font_size = nil, -- internal
justified = nil, -- internal
fgcolor = Blitbuffer.COLOR_BLACK,
text_padding = Size.padding.large,
text_margin = Size.margin.small,
@ -67,28 +70,38 @@ local TextViewer = InputContainer:extend{
add_default_buttons = nil,
default_hold_callback = nil, -- on each default button
find_centered_lines_count = 5, -- line with find results to be not far from the center
text_type = "general",
text_types = {
general = { monospace_font = false, font_size = 20, justified = false },
file_content = { monospace_font = false, font_size = 20, justified = false },
book_info = { monospace_font = false, font_size = 20, justified = true },
bookmark = { monospace_font = false, font_size = 20, justified = true },
lookup = { monospace_font = false, font_size = 20, justified = false },
code = { monospace_font = true, font_size = 16, justified = false },
},
}
function TextViewer:init()
-- calculate window dimension
function TextViewer:init(reinit)
local screen_w = Screen:getWidth()
local screen_h = Screen:getHeight()
self.align = "center"
self.region = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
w = screen_w,
h = screen_h,
}
self.width = self.width or Screen:getWidth() - Screen:scaleBySize(30)
self.height = self.height or Screen:getHeight() - Screen:scaleBySize(30)
if self.justified == nil then
self.justified = G_reader_settings:nilOrTrue("dict_justify")
end
if self.text_font_face == nil then
self.text_font_face = "x_smallinfofont"
if self.text_font_size == nil then
self.text_font_size = G_reader_settings:readSetting("dict_font_size")
end
self.width = self.width or screen_w - Screen:scaleBySize(30)
self.height = self.height or screen_h - Screen:scaleBySize(30)
if not reinit then
local text_types = G_reader_settings:readSetting("textviewer_text_types")
local text_settings = text_types and text_types[self.text_type] or self.text_types[self.text_type]
self.monospace_font = text_settings.monospace_font
self.text_font_size = text_settings.font_size
self.justified = text_settings.justified
end
local text_font_face = self.monospace_font and "smallinfont" or "x_smallinfofont"
self._find_next = false
self._find_next_button = false
@ -100,9 +113,8 @@ function TextViewer:init()
if Device:isTouchDevice() then
local range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
w = screen_w,
h = screen_h,
}
self.ges_events = {
TapClose = {
@ -153,7 +165,7 @@ function TextViewer:init()
}
end
local titlebar = TitleBar:new{
self.titlebar = TitleBar:new{
width = self.width,
align = "left",
with_bottom_line = true,
@ -161,6 +173,8 @@ function TextViewer:init()
title_face = self.title_face,
title_multilines = self.title_multilines,
title_shrink_font_to_fit = self.title_shrink_font_to_fit,
left_icon = self.show_menu and "appbar.menu",
left_icon_tap_callback = function() self:showMenu() end,
close_callback = function() self:onClose() end,
show_parent = self,
}
@ -246,7 +260,7 @@ function TextViewer:init()
},
}
local buttons = self.buttons_table or {}
if self.add_default_buttons or not self.buttons_table then
if (self.add_default_buttons and not reinit) or not self.buttons_table then
table.insert(buttons, default_buttons)
end
self.button_table = ButtonTable:new{
@ -256,11 +270,11 @@ function TextViewer:init()
show_parent = self,
}
local textw_height = self.height - titlebar:getHeight() - self.button_table:getSize().h
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(self.text_font_face, self.text_font_size),
face = Font:getFace(text_font_face, self.text_font_size),
fgcolor = self.fgcolor,
width = self.width - 2*self.text_padding - 2*self.text_margin,
height = textw_height - 2*self.text_padding -2*self.text_margin,
@ -286,7 +300,7 @@ function TextViewer:init()
margin = 0,
background = Blitbuffer.COLOR_WHITE,
VerticalGroup:new{
titlebar,
self.titlebar,
CenterContainer:new{
dimen = Geom:new{
w = self.width,
@ -433,7 +447,7 @@ function TextViewer:onForwardingPanRelease(arg, ges)
end
function TextViewer:findDialog()
local input_dialog
local input_dialog, check_button_case
input_dialog = InputDialog:new{
title = _("Enter text to search for"),
input = self.search_value,
@ -464,15 +478,15 @@ function TextViewer:findDialog()
},
},
}
self.check_button_case = CheckButton:new{
check_button_case = CheckButton:new{
text = _("Case sensitive"),
checked = self.case_sensitive,
parent = input_dialog,
callback = function()
self.case_sensitive = self.check_button_case.checked
self.case_sensitive = check_button_case.checked
end,
}
input_dialog:addWidget(self.check_button_case)
input_dialog:addWidget(check_button_case)
UIManager:show(input_dialog)
input_dialog:onShowKeyboard(true)
@ -531,6 +545,75 @@ function TextViewer:handleTextSelection(text, hold_duration, start_idx, end_idx,
end
end
function TextViewer:reinit()
local text_settings = G_reader_settings:readSetting("textviewer_text_types", {})
text_settings[self.text_type] = { monospace_font = self.monospace_font, font_size = self.text_font_size, justified = self.justified }
local low, high = self.scroll_text_w.text_widget:getVisibleHeightRatios() -- try to keep position
local ratio = low == 0 and 0 or (low + high) / 2 -- if we are at the beginning, keep the first line visible
self:init(true) -- do not add default buttons once more
UIManager:setDirty("all", "partial", self.frame.dimen)
self.scroll_text_w:scrollToRatio(ratio, ratio == 0)
end
function TextViewer:showMenu()
local dialog
local buttons = {
{{
text_func = function()
return T(_("Font size: %1"), self.text_font_size)
end,
align = "left",
callback = function()
UIManager:close(dialog)
local SpinWidget = require("ui/widget/spinwidget")
local widget = SpinWidget:new{
title_text = _("Font size"),
value = self.text_font_size,
value_min = 12,
value_max = 30,
default_value = self.monospace_font and 16 or 20,
keep_shown_on_apply = true,
callback = function(spin)
self.text_font_size = spin.value
self:reinit()
end,
}
UIManager:show(widget)
end,
}},
{{
text = _("Monospace font"),
checked_func = function()
return self.monospace_font
end,
align = "left",
callback = function()
self.monospace_font = not self.monospace_font
self:reinit()
end,
}},
{{
text = _("Justify"),
checked_func = function()
return self.justified
end,
align = "left",
callback = function()
self.justified = not self.justified
self:reinit()
end,
}},
}
dialog = ButtonDialog:new{
shrink_unneeded_width = true,
buttons = buttons,
anchor = function()
return self.titlebar.left_button.image.dimen
end,
}
UIManager:show(dialog)
end
-- Register DocumentRegistry auxiliary provider.
function TextViewer:register(registry)
registry:addAuxProvider({
@ -555,8 +638,8 @@ function TextViewer.openFile(file)
UIManager:show(TextViewer:new{
title = file_path,
title_multilines = true,
justified = false,
text = file_content,
text_type = "file_content",
})
end
local attr = lfs.attributes(file)

@ -1,6 +1,5 @@
local BD = require("ui/bidi")
local ButtonDialog = require("ui/widget/buttondialog")
local CenterContainer = require("ui/widget/container/centercontainer")
local DocumentRegistry = require("document/documentregistry")
local ImageViewer = require("ui/widget/imageviewer")
local Menu = require("ui/widget/menu")
@ -11,7 +10,6 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer")
local ffiUtil = require("ffi/util")
local util = require("util")
local _ = require("gettext")
local Screen = require("device").screen
local T = ffiUtil.template
local ArchiveViewer = WidgetContainer:extend{
@ -74,15 +72,13 @@ function ArchiveViewer:openFile(file)
return
end
local item_table = self:getItemTable() -- root
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
}
self.menu = Menu:new{
title = filename,
item_table = self:getItemTable(),
covers_fullscreen = true,
is_borderless = true,
is_popout = false,
title_multilines = true,
show_parent = menu_container,
onMenuSelect = function(self_menu, item)
if item.is_file then
self:showFileDialog(item.path)
@ -92,15 +88,13 @@ function ArchiveViewer:openFile(file)
end
end,
close_callback = function()
UIManager:close(menu_container)
UIManager:close(self.menu)
if self.fm_updated then
self.ui:onRefresh()
end
end,
}
table.insert(menu_container, self.menu)
self.menu:switchItemTable(filename, item_table)
UIManager:show(menu_container)
UIManager:show(self.menu)
end
function ArchiveViewer:getZipListTable()
@ -177,12 +171,8 @@ function ArchiveViewer:getItemTable(path)
end
table.sort(dirs, sorting)
table.sort(files, sorting)
for _, v in ipairs(dirs) do
table.insert(item_table, v)
end
for _, v in ipairs(files) do
table.insert(item_table, v)
end
table.move(dirs, 1, #dirs, #item_table + 1, item_table)
table.move(files, 1, #files, #item_table + 1, item_table)
return item_table
end
@ -265,12 +255,13 @@ function ArchiveViewer:viewFile(filepath)
UIManager:show(viewer)
viewer:switchToImageNum(curr_index)
else
UIManager:show(TextViewer:new{
local viewer = TextViewer:new{
title = filepath,
title_multilines = true,
text = self:extractContent(filepath),
justified = false,
})
text_type = "file_content",
}
UIManager:show(viewer)
end
end

@ -687,6 +687,7 @@ function OPDSBrowser:showDownloads(item)
title = item.text,
title_multilines = true,
text = util.htmlToPlainTextIfHtml(item.content),
text_type = "book_info",
})
end,
},

@ -114,7 +114,7 @@ function PatchManagement:getSubMenu(priority)
textviewer = TextViewer:new{
title = patch,
text = patch_content,
justified = false,
text_type = "code",
}
UIManager:show(textviewer)
end

Loading…
Cancel
Save