mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
HTML dictionary support (#3573)
* Adds a generic HTML widget modeled after the text widget, and HTML dictionary support. HTML dictionaries can have their own CSS (for X.ifo it must be X.css). The base CSS just resets the margin and sets the font. Note that the widget doesn't handle links, that wasn't needed for the dictionary. Closes <https://github.com/koreader/koreader/issues/1776>. * Show tag stripped HTML if the dictionary entry isn't valid HTML * Simulate the normal <br/> behavior * Bump base
This commit is contained in:
150
frontend/ui/widget/scrollhtmlwidget.lua
Normal file
150
frontend/ui/widget/scrollhtmlwidget.lua
Normal file
@@ -0,0 +1,150 @@
|
||||
--[[--
|
||||
HTML widget with vertical scroll bar.
|
||||
--]]
|
||||
|
||||
local Device = require("device")
|
||||
local HtmlBoxWidget = require("ui/widget/htmlboxwidget")
|
||||
local Geom = require("ui/geometry")
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
||||
local HorizontalSpan = require("ui/widget/horizontalspan")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalScrollBar = require("ui/widget/verticalscrollbar")
|
||||
|
||||
local Input = Device.input
|
||||
local Screen = Device.screen
|
||||
|
||||
local ScrollHtmlWidget = InputContainer:new{
|
||||
html_body = nil,
|
||||
css = nil,
|
||||
default_font_size = 18,
|
||||
htmlbox_widget = nil,
|
||||
v_scroll_bar = nil,
|
||||
dialog = nil,
|
||||
dimen = nil,
|
||||
width = 0,
|
||||
height = 0,
|
||||
scroll_bar_width = Screen:scaleBySize(6),
|
||||
text_scroll_span = Screen:scaleBySize(12),
|
||||
}
|
||||
|
||||
function ScrollHtmlWidget:init()
|
||||
self.htmlbox_widget = HtmlBoxWidget:new{
|
||||
dimen = Geom:new{
|
||||
w = self.width - self.scroll_bar_width - self.text_scroll_span,
|
||||
h = self.height,
|
||||
},
|
||||
}
|
||||
|
||||
self.htmlbox_widget:setContent(self.html_body, self.css, self.default_font_size)
|
||||
|
||||
self.v_scroll_bar = VerticalScrollBar:new{
|
||||
enable = self.htmlbox_widget.page_count > 1,
|
||||
width = self.scroll_bar_width,
|
||||
height = self.height,
|
||||
}
|
||||
|
||||
self.v_scroll_bar:set((self.htmlbox_widget.page_number-1) / self.htmlbox_widget.page_count, self.htmlbox_widget.page_number / self.htmlbox_widget.page_count)
|
||||
|
||||
local horizontal_group = HorizontalGroup:new{}
|
||||
table.insert(horizontal_group, self.htmlbox_widget)
|
||||
table.insert(horizontal_group, HorizontalSpan:new{width=self.text_scroll_span})
|
||||
table.insert(horizontal_group, self.v_scroll_bar)
|
||||
self[1] = horizontal_group
|
||||
|
||||
self.dimen = Geom:new(self[1]:getSize())
|
||||
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events = {
|
||||
SwipeScrollText = {
|
||||
GestureRange:new{
|
||||
ges = "swipe",
|
||||
range = function() return self.dimen end,
|
||||
},
|
||||
},
|
||||
TapScrollText = { -- allow scrolling with tap
|
||||
GestureRange:new{
|
||||
ges = "tap",
|
||||
range = function() return self.dimen end,
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
if Device:hasKeyboard() or Device:hasKeys() then
|
||||
self.key_events = {
|
||||
ScrollDown = {{Input.group.PgFwd}, doc = "scroll down"},
|
||||
ScrollUp = {{Input.group.PgBack}, doc = "scroll up"},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function ScrollHtmlWidget:scrollText(direction)
|
||||
if direction == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if direction > 0 then
|
||||
if self.htmlbox_widget.page_number >= self.htmlbox_widget.page_count then
|
||||
return
|
||||
end
|
||||
|
||||
self.htmlbox_widget.page_number = self.htmlbox_widget.page_number + 1
|
||||
elseif direction < 0 then
|
||||
if self.htmlbox_widget.page_number <= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
self.htmlbox_widget.page_number = self.htmlbox_widget.page_number - 1
|
||||
end
|
||||
|
||||
self.v_scroll_bar:set((self.htmlbox_widget.page_number-1) / self.htmlbox_widget.page_count, self.htmlbox_widget.page_number / self.htmlbox_widget.page_count)
|
||||
|
||||
self.htmlbox_widget:freeBb()
|
||||
self.htmlbox_widget:_render()
|
||||
|
||||
UIManager:setDirty(self.dialog, function()
|
||||
return "partial", self.dimen
|
||||
end)
|
||||
end
|
||||
|
||||
function ScrollHtmlWidget:onScrollText(arg, ges)
|
||||
if ges.direction == "north" then
|
||||
self:scrollText(1)
|
||||
return true
|
||||
elseif ges.direction == "south" then
|
||||
self:scrollText(-1)
|
||||
return true
|
||||
end
|
||||
-- if swipe west/east, let it propagate up (e.g. for quickdictlookup to
|
||||
-- go to next/prev result)
|
||||
end
|
||||
|
||||
function ScrollHtmlWidget:onTapScrollText(arg, ges)
|
||||
if ges.pos.x < Screen:getWidth()/2 then
|
||||
if self.htmlbox_widget.page_number > 1 then
|
||||
self:scrollText(-1)
|
||||
return true
|
||||
end
|
||||
else
|
||||
if self.htmlbox_widget.page_number <= self.htmlbox_widget.page_count then
|
||||
self:scrollText(1)
|
||||
return true
|
||||
end
|
||||
end
|
||||
-- if we couldn't scroll (because we're already at top or bottom),
|
||||
-- let it propagate up (e.g. for quickdictlookup to go to next/prev result)
|
||||
end
|
||||
|
||||
function ScrollHtmlWidget:onScrollDown()
|
||||
self:scrollText(1)
|
||||
return true
|
||||
end
|
||||
|
||||
function ScrollHtmlWidget:onScrollUp()
|
||||
self:scrollText(-1)
|
||||
return true
|
||||
end
|
||||
|
||||
return ScrollHtmlWidget
|
||||
Reference in New Issue
Block a user