Files
koreader/frontend/ui/widget/scrolltextwidget.lua
NiLuJe fea0d8dbaf Another set of fixes (#4083)
* Make findcalibre actually useful

By setting SEARCH_LIBRARY_PATH when a Calibre tree is found, so that
book paths can properly be constructed.

Users should still very much set it themselves, but at least everything
works as intended when not, instead of mysteriously half-breaking later.

Drop the SetDefaults bits, it appeared to have been added to fix no-ops
detected by Luacheck, and it's actually non-functional, because
SetDefaults doesn't handle saving variables it did not itself assign.
So this was just causing the "Do you want to save new defaults" popup to
show up on exit, but it couldn't actually do anything useful (like, say,
save the new SEARCH_LIBRARY_PATH value).

fix #4082

* Better comments about the state of NaturalLight on the Clara, and how this might translate to the H2O²r2.

re #4015

* Make ScrolltextWidget refresh as "partial" only on actual Scroll events

Moving the cursor should stay "ui", or things gets annoying really fast
;).

re #4084

* Bump base to pickup ZMQ fixes (fix #4086)
2018-07-21 21:51:25 +02:00

236 lines
6.7 KiB
Lua

--[[--
Text widget with vertical scroll bar.
--]]
local Blitbuffer = require("ffi/blitbuffer")
local Device = require("device")
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 TextBoxWidget = require("ui/widget/textboxwidget")
local VerticalScrollBar = require("ui/widget/verticalscrollbar")
local UIManager = require("ui/uimanager")
local Input = Device.input
local Screen = Device.screen
local ScrollTextWidget = InputContainer:new{
text = nil,
charlist = nil,
charpos = nil,
top_line_num = nil,
editable = false,
justified = false,
face = nil,
fgcolor = Blitbuffer.COLOR_BLACK,
width = Screen:scaleBySize(400),
height = Screen:scaleBySize(20),
scroll_bar_width = Screen:scaleBySize(6),
text_scroll_span = Screen:scaleBySize(12),
dialog = nil,
images = nil,
}
function ScrollTextWidget:init()
self.text_widget = TextBoxWidget:new{
text = self.text,
charlist = self.charlist,
charpos = self.charpos,
top_line_num = self.top_line_num,
dialog = self.dialog,
editable = self.editable,
justified = self.justified,
face = self.face,
image_alt_face = self.image_alt_face,
fgcolor = self.fgcolor,
width = self.width - self.scroll_bar_width - self.text_scroll_span,
height = self.height,
images = self.images,
}
local visible_line_count = self.text_widget:getVisLineCount()
local total_line_count = self.text_widget:getAllLineCount()
self.v_scroll_bar = VerticalScrollBar:new{
enable = visible_line_count < total_line_count,
low = 0,
high = visible_line_count / total_line_count,
width = self.scroll_bar_width,
height = self.text_widget:getTextHeight(),
}
self:updateScrollBar()
local horizontal_group = HorizontalGroup:new{ align = "top" }
table.insert(horizontal_group, self.text_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 = {
ScrollText = {
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 ScrollTextWidget:unfocus()
self.text_widget:unfocus()
end
function ScrollTextWidget:focus()
self.text_widget:focus()
end
function ScrollTextWidget:getTextHeight()
return self.text_widget:getTextHeight()
end
function ScrollTextWidget:getLineHeight()
return self.text_widget:getLineHeight()
end
function ScrollTextWidget:getCharPos()
return self.text_widget:getCharPos()
end
function ScrollTextWidget:updateScrollBar(is_partial)
local low, high = self.text_widget:getVisibleHeightRatios()
if low ~= self.prev_low or high ~= self.prev_high then
self.prev_low = low
self.prev_high = high
self.v_scroll_bar:set(low, high)
local refreshfunc = "ui"
if is_partial then
refreshfunc = "partial"
end
UIManager:setDirty(self.dialog, function()
return refreshfunc, self.dimen
end)
end
end
function ScrollTextWidget:moveCursorToCharPos(charpos)
self.text_widget:moveCursorToCharPos(charpos)
self:updateScrollBar()
end
function ScrollTextWidget:moveCursorToXY(x, y, no_overflow)
self.text_widget:moveCursorToXY(x, y, no_overflow)
self:updateScrollBar()
end
function ScrollTextWidget:moveCursorLeft()
self.text_widget:moveCursorLeft();
self:updateScrollBar()
end
function ScrollTextWidget:moveCursorRight()
self.text_widget:moveCursorRight();
self:updateScrollBar()
end
function ScrollTextWidget:moveCursorUp()
self.text_widget:moveCursorUp();
self:updateScrollBar()
end
function ScrollTextWidget:moveCursorDown()
self.text_widget:moveCursorDown();
self:updateScrollBar()
end
function ScrollTextWidget:scrollDown()
self.text_widget:scrollDown();
self:updateScrollBar(true)
end
function ScrollTextWidget:scrollUp()
self.text_widget:scrollUp();
self:updateScrollBar(true)
end
function ScrollTextWidget:scrollToTop()
self.text_widget:scrollToTop();
self:updateScrollBar(true)
end
function ScrollTextWidget:scrollToBottom()
self.text_widget:scrollToBottom();
self:updateScrollBar(true)
end
function ScrollTextWidget:scrollText(direction)
if direction == 0 then return end
if direction > 0 then
self.text_widget:scrollDown()
else
self.text_widget:scrollUp()
end
self:updateScrollBar(true)
end
function ScrollTextWidget:scrollToRatio(ratio)
self.text_widget:scrollToRatio(ratio)
self:updateScrollBar(true)
end
function ScrollTextWidget: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 ScrollTextWidget:onTapScrollText(arg, ges)
if self.editable then
-- Tap is used to position cursor
return false
end
-- same tests as done in TextBoxWidget:scrollUp/Down
if ges.pos.x < Screen:getWidth()/2 then
if self.text_widget.virtual_line_num > 1 then
self:scrollText(-1)
return true
end
else
if self.text_widget.virtual_line_num + self.text_widget:getVisLineCount() <= #self.text_widget.vertical_string_list 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 ScrollTextWidget:onScrollDown()
self:scrollText(1)
return true
end
function ScrollTextWidget:onScrollUp()
self:scrollText(-1)
return true
end
return ScrollTextWidget