mirror of
https://github.com/koreader/koreader
synced 2024-10-31 21:20:20 +00:00
06a8a33d39
* 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
151 lines
4.4 KiB
Lua
151 lines
4.4 KiB
Lua
--[[--
|
|
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
|