mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Font list menu: allow sorting by more recently set (#10662)
- Add a toggle in Font settings> allowing showing font ordered by most recently selected (long-press on it allows clearing this history). - Keep in G_reader_settings a list of known fonts, so we can notice newly added user fonts, and put them at the start of the most recently selected. Show these new fonts with a symbol in the menu. - TouchMenu: allows for a flag to trigger menu refresh when going up.
This commit is contained in:
@@ -14,8 +14,10 @@ local Notification = require("ui/widget/notification")
|
||||
local Screen = require("device").screen
|
||||
local UIManager = require("ui/uimanager")
|
||||
local cre -- Delayed loading
|
||||
local T = require("ffi/util").template
|
||||
local logger = require("logger")
|
||||
local util = require("util")
|
||||
local _ = require("gettext")
|
||||
local T = require("ffi/util").template
|
||||
local C_ = _.pgettext
|
||||
local optionsutil = require("ui/data/optionsutil")
|
||||
|
||||
@@ -30,8 +32,19 @@ local ReaderFont = InputContainer:extend{
|
||||
steps = {0,1,1,1,1,1,2,2,2,3,3,3,4,4,5},
|
||||
}
|
||||
|
||||
-- Keep a list of the new fonts seen at launch
|
||||
local newly_added_fonts = nil -- not yet filled
|
||||
|
||||
function ReaderFont:init()
|
||||
self:registerKeyEvents()
|
||||
self:setupFaceMenuTable()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
-- NOP our own gesture handling
|
||||
self.ges_events = nil
|
||||
end
|
||||
|
||||
function ReaderFont:setupFaceMenuTable()
|
||||
logger.dbg("building font face menu table")
|
||||
-- Build face_table for menu
|
||||
self.face_table = {}
|
||||
-- Font settings
|
||||
@@ -62,6 +75,7 @@ function ReaderFont:init()
|
||||
-- Font list
|
||||
cre = require("document/credocument"):engineInit()
|
||||
local face_list = cre.getFontFaces()
|
||||
face_list = self:sortFaceList(face_list)
|
||||
for k, v in ipairs(face_list) do
|
||||
local font_filename, font_faceindex, is_monospace = cre.getFontFaceFilenameAndFaceIndex(v)
|
||||
table.insert(self.face_table, {
|
||||
@@ -86,6 +100,9 @@ function ReaderFont:init()
|
||||
if v == fallback_font then
|
||||
text = text .. " <20>"
|
||||
end
|
||||
if newly_added_fonts[v] then
|
||||
text = text .. " \u{EA93}" -- "NEW" in a black square, from nerdfont
|
||||
end
|
||||
return text
|
||||
end,
|
||||
font_func = function(size)
|
||||
@@ -97,6 +114,10 @@ function ReaderFont:init()
|
||||
end,
|
||||
callback = function()
|
||||
self:onSetFont(v)
|
||||
-- We add it to the recently selected list only for tap on the
|
||||
-- menu item (and not when :onSetFont() would be triggered by
|
||||
-- a gesture/profile), which may be convenient for some users.
|
||||
self:addToRecentlySelectedList(v)
|
||||
end,
|
||||
hold_callback = function(touchmenu_instance)
|
||||
self:makeDefault(v, is_monospace, touchmenu_instance)
|
||||
@@ -107,13 +128,18 @@ function ReaderFont:init()
|
||||
menu_item_id = v,
|
||||
})
|
||||
end
|
||||
self.face_table.refresh_func = function()
|
||||
self:setupFaceMenuTable()
|
||||
-- This might be used by TouchMenu to refresh its font list menu,
|
||||
-- so return the newly created menu table.
|
||||
return self.face_table
|
||||
end
|
||||
self.face_table.open_on_menu_item_id_func = function()
|
||||
return self.font_face
|
||||
end
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
|
||||
-- NOP our own gesture handling
|
||||
self.ges_events = nil
|
||||
-- Have TouchMenu show half of the usual nb of items, so we
|
||||
-- have more room to see how the text looks with that font
|
||||
self.face_table.max_per_page = 5
|
||||
end
|
||||
|
||||
function ReaderFont:onGesture() end
|
||||
@@ -393,15 +419,17 @@ function ReaderFont:makeDefault(face, is_monospace, touchmenu_instance)
|
||||
end
|
||||
|
||||
function ReaderFont:addToMainMenu(menu_items)
|
||||
-- Have TouchMenu show half of the usual nb of items, so we
|
||||
-- have more room to see how the text looks with that font
|
||||
self.face_table.max_per_page = 5
|
||||
-- insert table to main reader menu
|
||||
menu_items.change_font = {
|
||||
text_func = function()
|
||||
return T(_("Font: %1"), BD.wrap(self.font_face))
|
||||
end,
|
||||
sub_item_table = self.face_table,
|
||||
sub_item_table_func = function()
|
||||
if self.face_table.needs_refresh and self.face_table.refresh_func then
|
||||
self.face_table.refresh_func()
|
||||
end
|
||||
return self.face_table
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
@@ -723,6 +751,35 @@ function ReaderFont:getFontSettingsTable()
|
||||
G_reader_settings:flipNilOrTrue("font_menu_use_font_face")
|
||||
end,
|
||||
help_text = _([[In the font menu, display each font name with its own font face.]]),
|
||||
})
|
||||
|
||||
table.insert(settings_table, {
|
||||
text = _("Sort fonts by recently selected"),
|
||||
checked_func = function()
|
||||
return G_reader_settings:isTrue("font_menu_sort_by_recently_selected")
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:flipTrue("font_menu_sort_by_recently_selected")
|
||||
self.face_table.needs_refresh = true
|
||||
end,
|
||||
hold_callback = function()
|
||||
UIManager:show(ConfirmBox:new{
|
||||
text = _([[
|
||||
The font list menu can show fonts sorted by name or by most recently selected.
|
||||
New fonts discovered at KOReader startup will be shown first.
|
||||
|
||||
Do you want to clear the history of selected fonts?]]),
|
||||
ok_text = _("Clear"),
|
||||
ok_callback = function()
|
||||
G_reader_settings:delSetting("cre_fonts_recently_selected")
|
||||
-- Recreate it now, sorted alphabetically (we may not go visit
|
||||
-- and refresh the font menu until quit, but we want to be able
|
||||
-- to notice newly added fonts at next startup).
|
||||
self:sortFaceList(cre.getFontFaces())
|
||||
self.face_table.needs_refresh = true
|
||||
end,
|
||||
})
|
||||
end,
|
||||
separator = true,
|
||||
})
|
||||
|
||||
@@ -808,6 +865,65 @@ This setting allows scaling all monospace fonts by this percentage so they can f
|
||||
return settings_table
|
||||
end
|
||||
|
||||
function ReaderFont:addToRecentlySelectedList(face)
|
||||
local idx = util.arrayContains(self.fonts_recently_selected, face)
|
||||
if idx then
|
||||
table.remove(self.fonts_recently_selected, idx)
|
||||
end
|
||||
table.insert(self.fonts_recently_selected, 1, face)
|
||||
if G_reader_settings:isTrue("font_menu_sort_by_recently_selected") then
|
||||
self.face_table.needs_refresh = true
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderFont:sortFaceList(face_list)
|
||||
self.fonts_recently_selected = G_reader_settings:readSetting("cre_fonts_recently_selected")
|
||||
if not self.fonts_recently_selected then
|
||||
-- Init this list with the alphabetical list we got
|
||||
self.fonts_recently_selected = face_list
|
||||
G_reader_settings:saveSetting("cre_fonts_recently_selected", self.fonts_recently_selected)
|
||||
-- We got no list of previously known fonts, so we can't say which are new.
|
||||
newly_added_fonts = {}
|
||||
return face_list
|
||||
end
|
||||
if not newly_added_fonts then
|
||||
-- First call after launch: check for fonts not yet known
|
||||
newly_added_fonts = {}
|
||||
local seen_fonts = {}
|
||||
for _, face in ipairs(self.fonts_recently_selected) do
|
||||
seen_fonts[face] = false -- was there last time, might no longer be now
|
||||
end
|
||||
for _, face in ipairs(face_list) do
|
||||
if seen_fonts[face] == nil then -- not known
|
||||
newly_added_fonts[face] = true
|
||||
-- Add newly seen fonts at start of the recently set list,
|
||||
-- so the user can see and test them more easily.
|
||||
table.insert(self.fonts_recently_selected, 1, face)
|
||||
end
|
||||
seen_fonts[face] = true
|
||||
end
|
||||
-- Remove no-longer-there fonts from our list
|
||||
util.arrayRemove(self.fonts_recently_selected, function(t, i, j)
|
||||
return seen_fonts[t[i]]
|
||||
end)
|
||||
end
|
||||
if G_reader_settings:isTrue("font_menu_sort_by_recently_selected") then
|
||||
return self.fonts_recently_selected
|
||||
end
|
||||
-- Otherwise, return face_list as we got it, alphabetically (as sorted by crengine),
|
||||
-- but still with newly added fonts first
|
||||
if next(newly_added_fonts) then
|
||||
local move_idx = 1
|
||||
for i=1, #face_list do
|
||||
if newly_added_fonts[face_list[i]] then
|
||||
table.insert(face_list, move_idx, table.remove(face_list, i))
|
||||
move_idx = move_idx + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return face_list
|
||||
end
|
||||
|
||||
-- Default sample file
|
||||
local FONT_TEST_DEFAULT_SAMPLE_PATH = "frontend/ui/elements/font-test-sample-default.template"
|
||||
-- Users can set their own sample file, that will be used if found
|
||||
|
||||
@@ -798,6 +798,11 @@ end
|
||||
function TouchMenu:backToUpperMenu(no_close)
|
||||
if #self.item_table_stack ~= 0 then
|
||||
self.item_table = table.remove(self.item_table_stack)
|
||||
-- Allow a menu table to refresh itself when going up (ie. from a setting
|
||||
-- submenu that may want to have its parent menu updated).
|
||||
if self.item_table.needs_refresh and self.item_table.refresh_func then
|
||||
self.item_table = self.item_table.refresh_func()
|
||||
end
|
||||
self.page = 1
|
||||
if self.parent_id then
|
||||
self:_recalculatePageLayout() -- we need an accurate self.perpage
|
||||
|
||||
Reference in New Issue
Block a user