diff --git a/frontend/ui/elements/menu_keyboard_layout.lua b/frontend/ui/elements/menu_keyboard_layout.lua index 0b78ef3c6..efbe7e208 100644 --- a/frontend/ui/elements/menu_keyboard_layout.lua +++ b/frontend/ui/elements/menu_keyboard_layout.lua @@ -9,46 +9,80 @@ local TextWidget = require("ui/widget/textwidget") local UIManager = require("ui/uimanager") local VirtualKeyboard = require("ui/widget/virtualkeyboard") local Screen = Device.screen -local T = require("ffi/util").template -local logger = require("logger") +local T = FFIUtil.template local util = require("util") local _ = require("gettext") local input_dialog, check_button_bold, check_button_border, check_button_compact --- Returns a string with all selected keyboard layouts (comma separated) and --- the count of the selectecd layouts. --- If compact is set, only the abbreviations and the count are returned. -local function getActivatedKeyboards(compact) +local function getOrderedActivatedKeyboardLayouts() local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) local activated_keyboards = {} - for lang, __ in FFIUtil.orderedPairs(VirtualKeyboard.lang_to_keyboard_layout) do - if util.arrayContains(keyboard_layouts, lang) then - if compact then - table.insert(activated_keyboards, lang) - else - table.insert(activated_keyboards, Language:getLanguageName(lang)) - end + for _, lang in ipairs(keyboard_layouts) do + if VirtualKeyboard.lang_to_keyboard_layout[lang] then + table.insert(activated_keyboards, lang) end end - if #activated_keyboards == 0 then - logger.dbg("menu_keyboard_layout: use default keyboard") - if compact then - return VirtualKeyboard:getKeyboardLayout(), 1 - else - return Language:getLanguageName(VirtualKeyboard:getKeyboardLayout()), 1 + if #activated_keyboards == 0 then -- use default keyboard + table.insert(activated_keyboards, VirtualKeyboard:getKeyboardLayout()) + elseif #activated_keyboards > 1 then + table.sort(activated_keyboards) + end + return activated_keyboards +end + +-- Returns a string with all selected keyboard layouts (comma separated) and +-- the count of the selectecd layouts. +-- If compact is set, only the abbreviations and the count are returned. +local function getActivatedKeyboardsStringCount(compact) + local activated_keyboards = getOrderedActivatedKeyboardLayouts() + if not compact then + for i, lang in ipairs(activated_keyboards) do + activated_keyboards[i] = Language:getLanguageName(lang) end end return table.concat(activated_keyboards, ", "), #activated_keyboards end -local function isKeyboardLayoutActive(lang) - if VirtualKeyboard:getKeyboardLayout() == lang then - return true +local function genKeyboardLayoutsSubmenu() + local item_table = {} + for lang, keyboard_layout in FFIUtil.orderedPairs(VirtualKeyboard.lang_to_keyboard_layout) do + table.insert(item_table, { + text_func = function() + local text = T("%1 (%2)", Language:getLanguageName(lang), lang:sub(1, 2)) + if G_reader_settings:readSetting("keyboard_layout_default") == lang then + text = text .. " ★" + end + return text + end, + checked_func = function() + local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) + return util.arrayContains(keyboard_layouts, lang) + end, + callback = function() + local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) + local layout_index = util.arrayContains(keyboard_layouts, lang) + if layout_index then + table.remove(keyboard_layouts, layout_index) + else + if #keyboard_layouts < 4 then + table.insert(keyboard_layouts, lang) + else -- no more space in the 'globe' popup + local InfoMessage = require("ui/widget/infomessage") + UIManager:show(InfoMessage:new{ + text = _("Up to four layouts can be enabled."), + timeout = 2, + }) + end + end + end, + hold_callback = function(touchmenu_instance) + G_reader_settings:saveSetting("keyboard_layout_default", lang) + touchmenu_instance:updateItems() + end, + }) end - - local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) - return util.arrayContains(keyboard_layouts, lang) + return item_table end -- Generate the language specific settings menu on demand, and only for active layouts, @@ -56,12 +90,13 @@ end local function genLayoutSpecificSubmenu() local item_table = {} - for lang, __ in FFIUtil.orderedPairs(VirtualKeyboard.lang_has_submenu) do - if isKeyboardLayoutActive(lang) then + local activated_keyboards = getOrderedActivatedKeyboardLayouts() + for _, lang in ipairs(activated_keyboards) do + if VirtualKeyboard.lang_has_submenu[lang] then local keyboard_layout = VirtualKeyboard.lang_to_keyboard_layout[lang] local kb_pkg = "ui/data/keyboardlayouts/" .. keyboard_layout table.insert(item_table, { - text = Language:getLanguageName(lang), + text = T("%1 (%2)", Language:getLanguageName(lang), lang), sub_item_table_func = function() local keyboard = require(kb_pkg) if keyboard.genMenuItems ~= nil then @@ -89,9 +124,8 @@ end local sub_item_table = { { text_func = function() - local activated_keyboards, nb_keyboards = getActivatedKeyboards() - local item_text = activated_keyboards and T(_("Keyboard layouts: %1"), activated_keyboards) - or _("Keyboard layouts") + local activated_keyboards, nb_keyboards = getActivatedKeyboardsStringCount() + local item_text = T(_("Keyboard layouts: %1"), activated_keyboards) -- get width of text local tmp = TextWidget:new{ @@ -103,13 +137,18 @@ local sub_item_table = { local checked_widget = CheckMark:new{ -- for layout, to :getSize() checked = true, } - if item_text_w >= Screen:getWidth()- 2*Size.padding.default - checked_widget:getSize().w then + if item_text_w >= Screen:getWidth() - 2*Size.padding.default - checked_widget:getSize().w then item_text = T(_("Keyboard layouts (%1)"), nb_keyboards) end return item_text end, - sub_item_table = {}, + sub_item_table_func = genKeyboardLayoutsSubmenu, + }, + { + text = _("Layout-specific keyboard settings"), + -- Lazy-loaded to avoid pinning potentially unnecessary data + sub_item_table_func = genLayoutSpecificSubmenu, }, { text = _("Remember last layout"), @@ -122,17 +161,29 @@ local sub_item_table = { separator = true, }, { - text = _("Keyboard settings"), + text = _("Swipe to input additional characters"), + checked_func = function() + return G_reader_settings:nilOrTrue("keyboard_swipes_enabled") + end, + callback = function() + G_reader_settings:flipNilOrTrue("keyboard_swipes_enabled") + end, + }, + { + text = _("Keyboard appearance settings"), keep_menu_open = true, callback = function(touchmenu_instance) - input_dialog = require("ui/widget/inputdialog"):new{ + local InputDialog = require("ui/widget/inputdialog") + input_dialog = InputDialog:new{ title = _("Keyboard font size"), + -- do not use input_type = "number" to see letters on the keyboard input = tostring(G_reader_settings:readSetting("keyboard_key_font_size", VirtualKeyboard.default_label_size)), input_hint = "(16 - 30)", buttons = { { { text = _("Close"), + id = "close", callback = function() UIManager:close(input_dialog) end, @@ -181,49 +232,6 @@ local sub_item_table = { input_dialog:onShowKeyboard() end, }, - { - text = _("Layout-specific keyboard settings"), - -- Lazy-loaded to avoid pinning potentially unnecessary data - sub_item_table_func = genLayoutSpecificSubmenu, - } } -for lang, keyboard_layout in FFIUtil.orderedPairs(VirtualKeyboard.lang_to_keyboard_layout) do - table.insert(sub_item_table[1].sub_item_table, { - text_func = function() - local text = Language:getLanguageName(lang) .. " (" .. string.sub(lang, 1, 2) ..")" - if G_reader_settings:readSetting("keyboard_layout_default") == lang then - text = text .. " ★" - end - return text - end, - checked_func = function() - local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) - return util.arrayContains(keyboard_layouts, lang) - end, - callback = function() - local keyboard_layouts = G_reader_settings:readSetting("keyboard_layouts", {}) - local layout_index = util.arrayContains(keyboard_layouts, lang) - if layout_index then - table.remove(keyboard_layouts, layout_index) - else - if #keyboard_layouts < 4 then - table.insert(keyboard_layouts, lang) - else -- no more space in the 'globe' popup - UIManager:show(require("ui/widget/infomessage"):new{ - text = _("Up to four layouts can be enabled."), - timeout = 2, - }) - return - end - end - G_reader_settings:saveSetting("keyboard_layouts", keyboard_layouts) - end, - hold_callback = function(touchmenu_instance) - G_reader_settings:saveSetting("keyboard_layout_default", lang) - if touchmenu_instance then touchmenu_instance:updateItems() end - end, - }) -end - return sub_item_table