mirror of https://github.com/koreader/koreader
Refactored to use strictly locals
parent
8efdff65d3
commit
ef111b99c6
@ -0,0 +1,19 @@
|
|||||||
|
--[[
|
||||||
|
Inheritable abstraction for cache items
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local CacheItem = {
|
||||||
|
size = 64, -- some reasonable default for simple Lua values / small tables
|
||||||
|
}
|
||||||
|
|
||||||
|
function CacheItem:new(o)
|
||||||
|
o = o or {}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function CacheItem:onFree()
|
||||||
|
end
|
||||||
|
|
||||||
|
return CacheItem
|
@ -0,0 +1,35 @@
|
|||||||
|
--[[
|
||||||
|
This is a registry for document providers
|
||||||
|
]]--
|
||||||
|
local DocumentRegistry = {
|
||||||
|
providers = { }
|
||||||
|
}
|
||||||
|
|
||||||
|
function DocumentRegistry:addProvider(extension, mimetype, provider)
|
||||||
|
table.insert(self.providers, { extension = extension, mimetype = mimetype, provider = provider })
|
||||||
|
end
|
||||||
|
|
||||||
|
function DocumentRegistry:getProvider(file)
|
||||||
|
-- TODO: some implementation based on mime types?
|
||||||
|
local extension = string.lower(string.match(file, ".+%.([^.]+)") or "")
|
||||||
|
for _, provider in ipairs(self.providers) do
|
||||||
|
if extension == provider.extension then
|
||||||
|
return provider.provider
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DocumentRegistry:openDocument(file)
|
||||||
|
local provider = self:getProvider(file)
|
||||||
|
if provider ~= nil then
|
||||||
|
return provider:new{file = file}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- load implementations:
|
||||||
|
|
||||||
|
require("document/pdfdocument"):register(DocumentRegistry)
|
||||||
|
require("document/djvudocument"):register(DocumentRegistry)
|
||||||
|
require("document/credocument"):register(DocumentRegistry)
|
||||||
|
|
||||||
|
return DocumentRegistry
|
@ -0,0 +1,12 @@
|
|||||||
|
local CacheItem = require("cacheitem")
|
||||||
|
|
||||||
|
local TileCacheItem = CacheItem:new{}
|
||||||
|
|
||||||
|
function TileCacheItem:onFree()
|
||||||
|
if self.bb.free then
|
||||||
|
DEBUG("free blitbuffer", self.bb)
|
||||||
|
self.bb:free()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TileCacheItem
|
@ -1,11 +1,16 @@
|
|||||||
|
|
||||||
lua_gettext.init("./i18n", "koreader")
|
lua_gettext.init("./i18n", "koreader")
|
||||||
|
|
||||||
|
local GetText = {}
|
||||||
|
local GetText_mt = {}
|
||||||
|
|
||||||
function _(string)
|
function GetText_mt.__call(gettext, string)
|
||||||
return lua_gettext.translate(string)
|
return lua_gettext.translate(string)
|
||||||
end
|
end
|
||||||
|
|
||||||
function gettextChangeLang(new_lang)
|
function GetText.changeLang(new_lang)
|
||||||
lua_gettext.change_lang(new_lang)
|
lua_gettext.change_lang(new_lang)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
setmetatable(GetText, GetText_mt)
|
||||||
|
|
||||||
|
return GetText
|
||||||
|
@ -1,49 +1,54 @@
|
|||||||
|
local _ = require("gettext")
|
||||||
|
|
||||||
SCREEN_MODE_STR = _("Screen Mode")
|
local S = {}
|
||||||
PAGE_CROP_STR = _("Page Crop")
|
|
||||||
FULL_SCREEN_STR = _("Full Screen")
|
|
||||||
SCROLL_MODE_STR = _("Scroll Mode")
|
|
||||||
PAGE_MARGIN_STR = _("Page Margin")
|
|
||||||
LINE_SPACING_STR = _("Line Spacing")
|
|
||||||
COLUMNS_STR = _("Columns")
|
|
||||||
TEXT_ALIGN_STR = _("Text Align")
|
|
||||||
FONTSIZE_FINE_TUNING_STR = _("Fine Tuning")
|
|
||||||
CONTRAST_STR = _("Contrast")
|
|
||||||
REFLOW_STR = _("Reflow")
|
|
||||||
DOC_LANG_STR = _("Document Language")
|
|
||||||
VERTICAL_TEXT_STR = _("Vertical Text")
|
|
||||||
WORD_GAP_STR = _("Word Gap")
|
|
||||||
DEFECT_SIZE_STR = _("Defect Size")
|
|
||||||
RENDER_QUALITY_STR = _("Render Quality")
|
|
||||||
AUTO_STRAIGHTEN_STR = _("Auto Straighten")
|
|
||||||
INDENTATION_STR = _("Indentation")
|
|
||||||
FONT_WEIGHT_STR = _("Font weight")
|
|
||||||
GAMMA_STR = _("Gamma")
|
|
||||||
VIEW_MODE_STR = _("View mode")
|
|
||||||
EMBEDDED_STYLE_STR = _("Embedded style")
|
|
||||||
|
|
||||||
ON_STR = _("on")
|
S.SCREEN_MODE = _("Screen Mode")
|
||||||
OFF_STR = _("off")
|
S.PAGE_CROP = _("Page Crop")
|
||||||
AUTO_STR = _("auto")
|
S.FULL_SCREEN = _("Full Screen")
|
||||||
MANUAL_STR = _("manual")
|
S.SCROLL_MODE = _("Scroll Mode")
|
||||||
SEMIAUTO_STR = _("semi-auto")
|
S.PAGE_MARGIN = _("Page Margin")
|
||||||
SMALL_STR = _("small")
|
S.LINE_SPACING = _("Line Spacing")
|
||||||
MEDIUM_STR = _("medium")
|
S.COLUMNS = _("Columns")
|
||||||
LARGE_STR = _("large")
|
S.TEXT_ALIGN = _("Text Align")
|
||||||
DECREASE_STR = _("decrease")
|
S.FONTSIZE_FINE_TUNING = _("Fine Tuning")
|
||||||
INCREASE_STR = _("increase")
|
S.CONTRAST = _("Contrast")
|
||||||
LIGHTEST_STR = _("lightest")
|
S.REFLOW = _("Reflow")
|
||||||
LIGHTER_STR = _("lighter")
|
S.DOC_LANG = _("Document Language")
|
||||||
DEFAULT_STR = _("default")
|
S.VERTICAL_TEXT = _("Vertical Text")
|
||||||
DARKER_STR = _("darker")
|
S.WORD_GAP = _("Word Gap")
|
||||||
DARKEST_STR = _("darkest")
|
S.DEFECT_SIZE = _("Defect Size")
|
||||||
LOW_STR = _("low")
|
S.RENDER_QUALITY = _("Render Quality")
|
||||||
HIGH_STR = _("high")
|
S.AUTO_STRAIGHTEN = _("Auto Straighten")
|
||||||
ZERO_DEG_STR = _("0 deg")
|
S.INDENTATION = _("Indentation")
|
||||||
FIVE_DEG_STR = _("5 deg")
|
S.FONT_WEIGHT = _("Font weight")
|
||||||
TEN_DEG_STR = _("10 deg")
|
S.GAMMA = _("Gamma")
|
||||||
PORTRAIT_STR = _("portrait")
|
S.VIEW_MODE = _("View mode")
|
||||||
LANDSCAPE_STR = _("landscape")
|
S.EMBEDDED_STYLE = _("Embedded style")
|
||||||
TOGGLE_BOLD_STR = _("toggle bold")
|
|
||||||
VIEW_SCROLL_STR = _("scroll")
|
S.ON = _("on")
|
||||||
VIEW_PAGE_STR = _("page")
|
S.OFF = _("off")
|
||||||
|
S.AUTO = _("auto")
|
||||||
|
S.MANUAL = _("manual")
|
||||||
|
S.SEMIAUTO = _("semi-auto")
|
||||||
|
S.SMALL = _("small")
|
||||||
|
S.MEDIUM = _("medium")
|
||||||
|
S.LARGE = _("large")
|
||||||
|
S.DECREASE = _("decrease")
|
||||||
|
S.INCREASE = _("increase")
|
||||||
|
S.LIGHTEST = _("lightest")
|
||||||
|
S.LIGHTER = _("lighter")
|
||||||
|
S.DEFAULT = _("default")
|
||||||
|
S.DARKER = _("darker")
|
||||||
|
S.DARKEST = _("darkest")
|
||||||
|
S.LOW = _("low")
|
||||||
|
S.HIGH = _("high")
|
||||||
|
S.ZERO_DEG = _("0 deg")
|
||||||
|
S.FIVE_DEG = _("5 deg")
|
||||||
|
S.TEN_DEG = _("10 deg")
|
||||||
|
S.PORTRAIT = _("portrait")
|
||||||
|
S.LANDSCAPE = _("landscape")
|
||||||
|
S.TOGGLE_BOLD = _("toggle bold")
|
||||||
|
S.VIEW_SCROLL = _("scroll")
|
||||||
|
S.VIEW_PAGE = _("page")
|
||||||
|
|
||||||
|
return S
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
local BaseFrontLight = {
|
||||||
|
min = 1, max = 10,
|
||||||
|
intensity = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function BaseFrontLight:init() end
|
||||||
|
function BaseFrontLight:toggle() end
|
||||||
|
function BaseFrontLight:setIntensityHW() end
|
||||||
|
|
||||||
|
function BaseFrontLight:setIntensity(intensity)
|
||||||
|
intensity = intensity < self.min and self.min or intensity
|
||||||
|
intensity = intensity > self.max and self.max or intensity
|
||||||
|
self.intensity = intensity
|
||||||
|
self:setIntensityHW()
|
||||||
|
end
|
||||||
|
|
||||||
|
return BaseFrontLight
|
@ -0,0 +1,38 @@
|
|||||||
|
local BaseFrontLight = require("ui/device/basefrontlight")
|
||||||
|
-- liblipclua, see require below
|
||||||
|
|
||||||
|
local KindleFrontLight = {
|
||||||
|
min = 0, max = 24,
|
||||||
|
kpw_fl = "/sys/devices/system/fl_tps6116x/fl_tps6116x0/fl_intensity",
|
||||||
|
intensity = nil,
|
||||||
|
lipc_handle = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function KindleFrontLight:init()
|
||||||
|
require "liblipclua"
|
||||||
|
self.lipc_handle = lipc.init("com.github.koreader")
|
||||||
|
if self.lipc_handle then
|
||||||
|
self.intensity = self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function KindleFrontLight:toggle()
|
||||||
|
local f = io.open(self.kpw_fl, "r")
|
||||||
|
local sysint = tonumber(f:read("*all"):match("%d+"))
|
||||||
|
f:close()
|
||||||
|
if sysint == 0 then
|
||||||
|
self:setIntensity(self.intensity)
|
||||||
|
else
|
||||||
|
os.execute("echo -n 0 > " .. self.kpw_fl)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
KindleFrontLight.setIntensity = BaseFrontLight.setIntensity
|
||||||
|
|
||||||
|
function KindleFrontLight:setIntensityHW()
|
||||||
|
if self.lipc_handle ~= nil then
|
||||||
|
self.lipc_handle:set_int_property("com.lab126.powerd", "flIntensity", self.intensity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return KindleFrontLight
|
@ -0,0 +1,28 @@
|
|||||||
|
local BaseFrontLight = require("ui/device/basefrontlight")
|
||||||
|
|
||||||
|
local KoboFrontLight = {
|
||||||
|
min = 1, max = 100,
|
||||||
|
intensity = 20,
|
||||||
|
restore_settings = true,
|
||||||
|
fl = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function KoboFrontLight:init()
|
||||||
|
self.fl = kobolight.open()
|
||||||
|
end
|
||||||
|
|
||||||
|
function KoboFrontLight:toggle()
|
||||||
|
if self.fl ~= nil then
|
||||||
|
self.fl:toggle()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
KoboFrontLight.setIntensity = BaseFrontLight.setIntensity
|
||||||
|
|
||||||
|
function KoboFrontLight:setIntensityHW()
|
||||||
|
if self.fl ~= nil then
|
||||||
|
self.fl:setBrightness(self.intensity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return KoboFrontLight
|
@ -0,0 +1,45 @@
|
|||||||
|
-- TimeVal
|
||||||
|
|
||||||
|
local GestureRange = {
|
||||||
|
ges = nil,
|
||||||
|
-- spatial range limits the gesture emitting position
|
||||||
|
range = nil,
|
||||||
|
-- temproal range limits the gesture emitting rate
|
||||||
|
rate = nil,
|
||||||
|
-- span limits of this gesture
|
||||||
|
scale = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function GestureRange:new(o)
|
||||||
|
local o = o or {}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function GestureRange:match(gs)
|
||||||
|
if gs.ges ~= self.ges then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if self.range then
|
||||||
|
if not self.range:contains(gs.pos) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self.rate then
|
||||||
|
local last_time = self.last_time or TimeVal:new{}
|
||||||
|
if gs.time - last_time > TimeVal:new{usec = 1000000 / self.rate} then
|
||||||
|
self.last_time = gs.time
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self.scale then
|
||||||
|
if self.scale[1] > gs.span or self.scale[2] < gs.span then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return GestureRange
|
@ -1,181 +0,0 @@
|
|||||||
--[[
|
|
||||||
Draw a border
|
|
||||||
|
|
||||||
@x: start position in x axis
|
|
||||||
@y: start position in y axis
|
|
||||||
@w: width of the border
|
|
||||||
@h: height of the border
|
|
||||||
@bw: line width of the border
|
|
||||||
@c: color for loading bar
|
|
||||||
@r: radius of for border's corner (nil or 0 means right corner border)
|
|
||||||
--]]
|
|
||||||
function blitbuffer.paintBorder(bb, x, y, w, h, bw, c, r)
|
|
||||||
x, y = math.ceil(x), math.ceil(y)
|
|
||||||
h, w = math.ceil(h), math.ceil(w)
|
|
||||||
if not r or r == 0 then
|
|
||||||
bb:paintRect(x, y, w, bw, c)
|
|
||||||
bb:paintRect(x, y+h-bw, w, bw, c)
|
|
||||||
bb:paintRect(x, y+bw, bw, h - 2*bw, c)
|
|
||||||
bb:paintRect(x+w-bw, y+bw, bw, h - 2*bw, c)
|
|
||||||
else
|
|
||||||
if h < 2*r then r = math.floor(h/2) end
|
|
||||||
if w < 2*r then r = math.floor(w/2) end
|
|
||||||
bb:paintRoundedCorner(x, y, w, h, bw, r, c)
|
|
||||||
bb:paintRect(r+x, y, w-2*r, bw, c)
|
|
||||||
bb:paintRect(r+x, y+h-bw, w-2*r, bw, c)
|
|
||||||
bb:paintRect(x, r+y, bw, h-2*r, c)
|
|
||||||
bb:paintRect(x+w-bw, r+y, bw, h-2*r, c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Fill a rounded corner rectangular area
|
|
||||||
|
|
||||||
@x: start position in x axis
|
|
||||||
@y: start position in y axis
|
|
||||||
@w: width of the area
|
|
||||||
@h: height of the area
|
|
||||||
@c: color used to fill the area
|
|
||||||
@r: radius of for four corners
|
|
||||||
--]]
|
|
||||||
function blitbuffer.paintRoundedRect(bb, x, y, w, h, c, r)
|
|
||||||
x, y = math.ceil(x), math.ceil(y)
|
|
||||||
h, w = math.ceil(h), math.ceil(w)
|
|
||||||
if not r or r == 0 then
|
|
||||||
bb:paintRect(x, y, w, h, c)
|
|
||||||
else
|
|
||||||
if h < 2*r then r = math.floor(h/2) end
|
|
||||||
if w < 2*r then r = math.floor(w/2) end
|
|
||||||
bb:paintBorder(x, y, w, h, r, c, r)
|
|
||||||
bb:paintRect(x+r, y+r, w-2*r, h-2*r, c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Draw a progress bar according to following args:
|
|
||||||
|
|
||||||
@x: start position in x axis
|
|
||||||
@y: start position in y axis
|
|
||||||
@w: width for progress bar
|
|
||||||
@h: height for progress bar
|
|
||||||
@load_m_w: width margin for loading bar
|
|
||||||
@load_m_h: height margin for loading bar
|
|
||||||
@load_percent: progress in percent
|
|
||||||
@c: color for loading bar
|
|
||||||
--]]
|
|
||||||
function blitbuffer.progressBar(bb, x, y, w, h,
|
|
||||||
load_m_w, load_m_h, load_percent, c)
|
|
||||||
if load_m_h*2 > h then
|
|
||||||
load_m_h = h/2
|
|
||||||
end
|
|
||||||
bb:paintBorder(x, y, w, h, 2, 15)
|
|
||||||
bb:paintRect(x+load_m_w, y+load_m_h,
|
|
||||||
(w-2*load_m_w)*load_percent, (h-2*load_m_h), c)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------
|
|
||||||
-- Start of Cursor class
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
Cursor = {
|
|
||||||
x_pos = 0,
|
|
||||||
y_pos = 0,
|
|
||||||
--color = 15,
|
|
||||||
h = 10,
|
|
||||||
w = nil,
|
|
||||||
line_w = nil,
|
|
||||||
is_cleared = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
function Cursor:new(o)
|
|
||||||
o = o or {}
|
|
||||||
o.x_pos = o.x_pos or self.x_pos
|
|
||||||
o.y_pos = o.y_pos or self.y_pos
|
|
||||||
o.line_width_factor = o.line_width_factor or 10
|
|
||||||
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
|
|
||||||
o:setHeight(o.h or self.h)
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:setHeight(h)
|
|
||||||
self.h = h
|
|
||||||
self.w = self.h / 3
|
|
||||||
self.line_w = math.floor(self.h / self.line_width_factor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:_draw(x, y)
|
|
||||||
local up_down_width = math.floor(self.line_w / 2)
|
|
||||||
local body_h = self.h - (up_down_width * 2)
|
|
||||||
-- paint upper horizontal line
|
|
||||||
fb.bb:invertRect(x, y, self.w, up_down_width)
|
|
||||||
-- paint middle vertical line
|
|
||||||
fb.bb:invertRect(x + (self.w / 2) - up_down_width, y + up_down_width,
|
|
||||||
self.line_w, body_h)
|
|
||||||
-- paint lower horizontal line
|
|
||||||
fb.bb:invertRect(x, y + body_h + up_down_width, self.w, up_down_width)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:draw()
|
|
||||||
if self.is_cleared then
|
|
||||||
self.is_cleared = false
|
|
||||||
self:_draw(self.x_pos, self.y_pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:clear()
|
|
||||||
if not self.is_cleared then
|
|
||||||
self.is_cleared = true
|
|
||||||
self:_draw(self.x_pos, self.y_pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:move(x_off, y_off)
|
|
||||||
self.x_pos = self.x_pos + x_off
|
|
||||||
self.y_pos = self.y_pos + y_off
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveHorizontal(x_off)
|
|
||||||
self.x_pos = self.x_pos + x_off
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveVertical(x_off)
|
|
||||||
self.y_pos = self.y_pos + y_off
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveAndDraw(x_off, y_off)
|
|
||||||
self:clear()
|
|
||||||
self:move(x_off, y_off)
|
|
||||||
self:draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveTo(x_pos, y_pos)
|
|
||||||
self.x_pos = x_pos
|
|
||||||
self.y_pos = y_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveToAndDraw(x_pos, y_pos)
|
|
||||||
self:clear()
|
|
||||||
self.x_pos = x_pos
|
|
||||||
self.y_pos = y_pos
|
|
||||||
self:draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveHorizontalAndDraw(x_off)
|
|
||||||
self:clear()
|
|
||||||
self:move(x_off, 0)
|
|
||||||
self:draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Cursor:moveVerticalAndDraw(y_off)
|
|
||||||
self:clear()
|
|
||||||
self:move(0, y_off)
|
|
||||||
self:draw()
|
|
||||||
end
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
local Configurable = {}
|
||||||
|
|
||||||
|
function Configurable:hash(sep)
|
||||||
|
local hash = ""
|
||||||
|
local excluded = {multi_threads = true,}
|
||||||
|
for key,value in pairs(self) do
|
||||||
|
if type(value) == "number" or type(value) == "string"
|
||||||
|
and not excluded[key] then
|
||||||
|
hash = hash..sep..value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
function Configurable:loadDefaults(config_options)
|
||||||
|
for i=1,#config_options do
|
||||||
|
local options = config_options[i].options
|
||||||
|
for j=1,#config_options[i].options do
|
||||||
|
local key = config_options[i].options[j].name
|
||||||
|
self[key] = config_options[i].options[j].default_value
|
||||||
|
if not self[key] then
|
||||||
|
self[key] = config_options[i].options[j].default_arg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Configurable:loadSettings(settings, prefix)
|
||||||
|
for key,value in pairs(self) do
|
||||||
|
if type(value) == "number" or type(value) == "string"
|
||||||
|
or type(value) == "table" then
|
||||||
|
local saved_value = settings:readSetting(prefix..key)
|
||||||
|
self[key] = (saved_value == nil) and self[key] or saved_value
|
||||||
|
--Debug("Configurable:loadSettings", "key", key, "saved value", saved_value,"Configurable.key", self[key])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--Debug("loaded config:", dump(Configurable))
|
||||||
|
end
|
||||||
|
|
||||||
|
function Configurable:saveSettings(settings, prefix)
|
||||||
|
for key,value in pairs(self) do
|
||||||
|
if type(value) == "number" or type(value) == "string"
|
||||||
|
or type(value) == "table" then
|
||||||
|
settings:saveSetting(prefix..key, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Configurable
|
@ -1,326 +0,0 @@
|
|||||||
require "ui/widget/base"
|
|
||||||
|
|
||||||
--[[
|
|
||||||
WidgetContainer is a container for another Widget
|
|
||||||
--]]
|
|
||||||
WidgetContainer = Widget:new()
|
|
||||||
|
|
||||||
function WidgetContainer:init()
|
|
||||||
if not self.dimen then
|
|
||||||
self.dimen = Geom:new{}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function WidgetContainer:getSize()
|
|
||||||
if self.dimen then
|
|
||||||
-- fixed size
|
|
||||||
return self.dimen
|
|
||||||
elseif self[1] then
|
|
||||||
-- return size of first child widget
|
|
||||||
return self[1]:getSize()
|
|
||||||
else
|
|
||||||
return Geom:new{ w = 0, h = 0 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
delete all child widgets
|
|
||||||
--]]
|
|
||||||
function WidgetContainer:clear()
|
|
||||||
while table.remove(self) do end
|
|
||||||
end
|
|
||||||
|
|
||||||
function WidgetContainer:paintTo(bb, x, y)
|
|
||||||
-- default to pass request to first child widget
|
|
||||||
if self[1] then
|
|
||||||
return self[1]:paintTo(bb, x, y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function WidgetContainer:propagateEvent(event)
|
|
||||||
-- propagate to children
|
|
||||||
for _, widget in ipairs(self) do
|
|
||||||
if widget:handleEvent(event) then
|
|
||||||
-- stop propagating when an event handler returns true
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Containers will pass events to children or react on them themselves
|
|
||||||
--]]
|
|
||||||
function WidgetContainer:handleEvent(event)
|
|
||||||
if not self:propagateEvent(event) then
|
|
||||||
-- call our own standard event handler
|
|
||||||
return Widget.handleEvent(self, event)
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function WidgetContainer:free()
|
|
||||||
for _, widget in ipairs(self) do
|
|
||||||
if widget.free then widget:free() end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
BottomContainer contains its content (1 widget) at the bottom of its own
|
|
||||||
dimensions
|
|
||||||
--]]
|
|
||||||
BottomContainer = WidgetContainer:new()
|
|
||||||
|
|
||||||
function BottomContainer:paintTo(bb, x, y)
|
|
||||||
local contentSize = self[1]:getSize()
|
|
||||||
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
|
||||||
-- throw error? paint to scrap buffer and blit partially?
|
|
||||||
-- for now, we ignore this
|
|
||||||
end
|
|
||||||
self[1]:paintTo(bb,
|
|
||||||
x + math.floor((self.dimen.w - contentSize.w)/2),
|
|
||||||
y + (self.dimen.h - contentSize.h))
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
CenterContainer centers its content (1 widget) within its own dimensions
|
|
||||||
--]]
|
|
||||||
CenterContainer = WidgetContainer:new()
|
|
||||||
|
|
||||||
function CenterContainer:paintTo(bb, x, y)
|
|
||||||
local contentSize = self[1]:getSize()
|
|
||||||
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
|
||||||
-- throw error? paint to scrap buffer and blit partially?
|
|
||||||
-- for now, we ignore this
|
|
||||||
end
|
|
||||||
local x_pos = x
|
|
||||||
local y_pos = y
|
|
||||||
if self.ignore ~= "height" then
|
|
||||||
y_pos = y + math.floor((self.dimen.h - contentSize.h)/2)
|
|
||||||
end
|
|
||||||
if self.ignore ~= "width" then
|
|
||||||
x_pos = x + math.floor((self.dimen.w - contentSize.w)/2)
|
|
||||||
end
|
|
||||||
self[1]:paintTo(bb, x_pos, y_pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
LeftContainer aligns its content (1 widget) at the left of its own dimensions
|
|
||||||
--]]
|
|
||||||
LeftContainer = WidgetContainer:new()
|
|
||||||
|
|
||||||
function LeftContainer:paintTo(bb, x, y)
|
|
||||||
local contentSize = self[1]:getSize()
|
|
||||||
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
|
||||||
-- throw error? paint to scrap buffer and blit partially?
|
|
||||||
-- for now, we ignore this
|
|
||||||
end
|
|
||||||
self[1]:paintTo(bb, x , y + math.floor((self.dimen.h - contentSize.h)/2))
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
RightContainer aligns its content (1 widget) at the right of its own dimensions
|
|
||||||
--]]
|
|
||||||
RightContainer = WidgetContainer:new()
|
|
||||||
|
|
||||||
function RightContainer:paintTo(bb, x, y)
|
|
||||||
local contentSize = self[1]:getSize()
|
|
||||||
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
|
||||||
-- throw error? paint to scrap buffer and blit partially?
|
|
||||||
-- for now, we ignore this
|
|
||||||
end
|
|
||||||
self[1]:paintTo(bb,
|
|
||||||
x + (self.dimen.w - contentSize.w),
|
|
||||||
y + math.floor((self.dimen.h - contentSize.h)/2))
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
A FrameContainer is some graphics content (1 widget) that is surrounded by a
|
|
||||||
frame
|
|
||||||
--]]
|
|
||||||
FrameContainer = WidgetContainer:new{
|
|
||||||
background = nil,
|
|
||||||
color = 15,
|
|
||||||
margin = 0,
|
|
||||||
radius = 0,
|
|
||||||
bordersize = 2,
|
|
||||||
padding = 5,
|
|
||||||
width = nil,
|
|
||||||
height = nil,
|
|
||||||
invert = false,
|
|
||||||
}
|
|
||||||
|
|
||||||
function FrameContainer:getSize()
|
|
||||||
local content_size = self[1]:getSize()
|
|
||||||
return Geom:new{
|
|
||||||
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
|
|
||||||
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function FrameContainer:paintTo(bb, x, y)
|
|
||||||
local my_size = self:getSize()
|
|
||||||
self.dimen = Geom:new{
|
|
||||||
x = x, y = y,
|
|
||||||
w = my_size.w,
|
|
||||||
h = my_size.h
|
|
||||||
}
|
|
||||||
local container_width = self.width or my_size.w
|
|
||||||
local container_height = self.height or my_size.h
|
|
||||||
|
|
||||||
--@TODO get rid of margin here? 13.03 2013 (houqp)
|
|
||||||
if self.background then
|
|
||||||
bb:paintRoundedRect(x, y, container_width, container_height,
|
|
||||||
self.background, self.radius)
|
|
||||||
end
|
|
||||||
if self.bordersize > 0 then
|
|
||||||
bb:paintBorder(x + self.margin, y + self.margin,
|
|
||||||
container_width - self.margin * 2,
|
|
||||||
container_height - self.margin * 2,
|
|
||||||
self.bordersize, self.color, self.radius)
|
|
||||||
end
|
|
||||||
if self[1] then
|
|
||||||
self[1]:paintTo(bb,
|
|
||||||
x + self.margin + self.bordersize + self.padding,
|
|
||||||
y + self.margin + self.bordersize + self.padding)
|
|
||||||
end
|
|
||||||
if self.invert then
|
|
||||||
bb:invertRect(x + self.bordersize, y + self.bordersize,
|
|
||||||
container_width - 2*self.bordersize,
|
|
||||||
container_height - 2*self.bordersize)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
an UnderlineContainer is a WidgetContainer that is able to paint
|
|
||||||
a line under its child node
|
|
||||||
--]]
|
|
||||||
|
|
||||||
UnderlineContainer = WidgetContainer:new{
|
|
||||||
linesize = 2,
|
|
||||||
padding = 1,
|
|
||||||
color = 0,
|
|
||||||
vertical_align = "top",
|
|
||||||
}
|
|
||||||
|
|
||||||
function UnderlineContainer:getSize()
|
|
||||||
return self:getContentSize()
|
|
||||||
end
|
|
||||||
|
|
||||||
function UnderlineContainer:getContentSize()
|
|
||||||
local contentSize = self[1]:getSize()
|
|
||||||
return Geom:new{
|
|
||||||
w = contentSize.w,
|
|
||||||
h = contentSize.h + self.linesize + self.padding
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function UnderlineContainer:paintTo(bb, x, y)
|
|
||||||
local container_size = self:getSize()
|
|
||||||
local content_size = self:getContentSize()
|
|
||||||
local p_y = y
|
|
||||||
if self.vertical_align == "center" then
|
|
||||||
p_y = math.floor((container_size.h - content_size.h) / 2) + y
|
|
||||||
elseif self.vertical_align == "bottom" then
|
|
||||||
p_y = (container_size.h - content_size.h) + y
|
|
||||||
end
|
|
||||||
self[1]:paintTo(bb, x, p_y)
|
|
||||||
bb:paintRect(x, y + container_size.h - self.linesize,
|
|
||||||
container_size.w, self.linesize, self.color)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
an InputContainer is an WidgetContainer that handles input events
|
|
||||||
|
|
||||||
an example for a key_event is this:
|
|
||||||
|
|
||||||
PanBy20 = {
|
|
||||||
{ "Shift", Input.group.Cursor },
|
|
||||||
seqtext = "Shift+Cursor",
|
|
||||||
doc = "pan by 20px",
|
|
||||||
event = "Pan", args = 20, is_inactive = true,
|
|
||||||
},
|
|
||||||
PanNormal = {
|
|
||||||
{ Input.group.Cursor },
|
|
||||||
seqtext = "Cursor",
|
|
||||||
doc = "pan by 10 px", event = "Pan", args = 10,
|
|
||||||
},
|
|
||||||
Quit = { {"Home"} },
|
|
||||||
|
|
||||||
it is suggested to reference configurable sequences from another table
|
|
||||||
and store that table as configuration setting
|
|
||||||
--]]
|
|
||||||
InputContainer = WidgetContainer:new{
|
|
||||||
vertical_align = "top",
|
|
||||||
}
|
|
||||||
|
|
||||||
function InputContainer:_init()
|
|
||||||
-- we need to do deep copy here
|
|
||||||
local new_key_events = {}
|
|
||||||
if self.key_events then
|
|
||||||
for k,v in pairs(self.key_events) do
|
|
||||||
new_key_events[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.key_events = new_key_events
|
|
||||||
|
|
||||||
local new_ges_events = {}
|
|
||||||
if self.ges_events then
|
|
||||||
for k,v in pairs(self.ges_events) do
|
|
||||||
new_ges_events[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.ges_events = new_ges_events
|
|
||||||
|
|
||||||
if not self.dimen then
|
|
||||||
self.dimen = Geom:new{}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function InputContainer:paintTo(bb, x, y)
|
|
||||||
self.dimen.x = x
|
|
||||||
self.dimen.y = y
|
|
||||||
if self[1] then
|
|
||||||
if self.vertical_align == "center" then
|
|
||||||
local content_size = self[1]:getSize()
|
|
||||||
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
|
|
||||||
else
|
|
||||||
self[1]:paintTo(bb, x, y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
the following handler handles keypresses and checks if they lead to a command.
|
|
||||||
if this is the case, we retransmit another event within ourselves
|
|
||||||
--]]
|
|
||||||
function InputContainer:onKeyPress(key)
|
|
||||||
for name, seq in pairs(self.key_events) do
|
|
||||||
if not seq.is_inactive then
|
|
||||||
for _, oneseq in ipairs(seq) do
|
|
||||||
if key:match(oneseq) then
|
|
||||||
local eventname = seq.event or name
|
|
||||||
return self:handleEvent(Event:new(eventname, seq.args, key))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function InputContainer:onGesture(ev)
|
|
||||||
for name, gsseq in pairs(self.ges_events) do
|
|
||||||
for _, gs_range in ipairs(gsseq) do
|
|
||||||
--DEBUG("gs_range", gs_range)
|
|
||||||
if gs_range:match(ev) then
|
|
||||||
local eventname = gsseq.event or name
|
|
||||||
return self:handleEvent(Event:new(eventname, gsseq.args, ev))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
BottomContainer contains its content (1 widget) at the bottom of its own
|
||||||
|
dimensions
|
||||||
|
--]]
|
||||||
|
local BottomContainer = WidgetContainer:new()
|
||||||
|
|
||||||
|
function BottomContainer:paintTo(bb, x, y)
|
||||||
|
local contentSize = self[1]:getSize()
|
||||||
|
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
||||||
|
-- throw error? paint to scrap buffer and blit partially?
|
||||||
|
-- for now, we ignore this
|
||||||
|
end
|
||||||
|
self[1]:paintTo(bb,
|
||||||
|
x + math.floor((self.dimen.w - contentSize.w)/2),
|
||||||
|
y + (self.dimen.h - contentSize.h))
|
||||||
|
end
|
||||||
|
|
||||||
|
return BottomContainer
|
@ -0,0 +1,25 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
CenterContainer centers its content (1 widget) within its own dimensions
|
||||||
|
--]]
|
||||||
|
local CenterContainer = WidgetContainer:new()
|
||||||
|
|
||||||
|
function CenterContainer:paintTo(bb, x, y)
|
||||||
|
local contentSize = self[1]:getSize()
|
||||||
|
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
||||||
|
-- throw error? paint to scrap buffer and blit partially?
|
||||||
|
-- for now, we ignore this
|
||||||
|
end
|
||||||
|
local x_pos = x
|
||||||
|
local y_pos = y
|
||||||
|
if self.ignore ~= "height" then
|
||||||
|
y_pos = y + math.floor((self.dimen.h - contentSize.h)/2)
|
||||||
|
end
|
||||||
|
if self.ignore ~= "width" then
|
||||||
|
x_pos = x + math.floor((self.dimen.w - contentSize.w)/2)
|
||||||
|
end
|
||||||
|
self[1]:paintTo(bb, x_pos, y_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
return CenterContainer
|
@ -0,0 +1,61 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
A FrameContainer is some graphics content (1 widget) that is surrounded by a
|
||||||
|
frame
|
||||||
|
--]]
|
||||||
|
local FrameContainer = WidgetContainer:new{
|
||||||
|
background = nil,
|
||||||
|
color = 15,
|
||||||
|
margin = 0,
|
||||||
|
radius = 0,
|
||||||
|
bordersize = 2,
|
||||||
|
padding = 5,
|
||||||
|
width = nil,
|
||||||
|
height = nil,
|
||||||
|
invert = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
function FrameContainer:getSize()
|
||||||
|
local content_size = self[1]:getSize()
|
||||||
|
return Geom:new{
|
||||||
|
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
|
||||||
|
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function FrameContainer:paintTo(bb, x, y)
|
||||||
|
local my_size = self:getSize()
|
||||||
|
self.dimen = Geom:new{
|
||||||
|
x = x, y = y,
|
||||||
|
w = my_size.w,
|
||||||
|
h = my_size.h
|
||||||
|
}
|
||||||
|
local container_width = self.width or my_size.w
|
||||||
|
local container_height = self.height or my_size.h
|
||||||
|
|
||||||
|
--@TODO get rid of margin here? 13.03 2013 (houqp)
|
||||||
|
if self.background then
|
||||||
|
bb:paintRoundedRect(x, y, container_width, container_height,
|
||||||
|
self.background, self.radius)
|
||||||
|
end
|
||||||
|
if self.bordersize > 0 then
|
||||||
|
bb:paintBorder(x + self.margin, y + self.margin,
|
||||||
|
container_width - self.margin * 2,
|
||||||
|
container_height - self.margin * 2,
|
||||||
|
self.bordersize, self.color, self.radius)
|
||||||
|
end
|
||||||
|
if self[1] then
|
||||||
|
self[1]:paintTo(bb,
|
||||||
|
x + self.margin + self.bordersize + self.padding,
|
||||||
|
y + self.margin + self.bordersize + self.padding)
|
||||||
|
end
|
||||||
|
if self.invert then
|
||||||
|
bb:invertRect(x + self.bordersize, y + self.bordersize,
|
||||||
|
container_width - 2*self.bordersize,
|
||||||
|
container_height - 2*self.bordersize)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return FrameContainer
|
@ -0,0 +1,94 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
local Event = require("ui/event")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
an InputContainer is an WidgetContainer that handles input events
|
||||||
|
|
||||||
|
an example for a key_event is this:
|
||||||
|
|
||||||
|
PanBy20 = {
|
||||||
|
{ "Shift", Input.group.Cursor },
|
||||||
|
seqtext = "Shift+Cursor",
|
||||||
|
doc = "pan by 20px",
|
||||||
|
event = "Pan", args = 20, is_inactive = true,
|
||||||
|
},
|
||||||
|
PanNormal = {
|
||||||
|
{ Input.group.Cursor },
|
||||||
|
seqtext = "Cursor",
|
||||||
|
doc = "pan by 10 px", event = "Pan", args = 10,
|
||||||
|
},
|
||||||
|
Quit = { {"Home"} },
|
||||||
|
|
||||||
|
it is suggested to reference configurable sequences from another table
|
||||||
|
and store that table as configuration setting
|
||||||
|
--]]
|
||||||
|
local InputContainer = WidgetContainer:new{
|
||||||
|
vertical_align = "top",
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputContainer:_init()
|
||||||
|
-- we need to do deep copy here
|
||||||
|
local new_key_events = {}
|
||||||
|
if self.key_events then
|
||||||
|
for k,v in pairs(self.key_events) do
|
||||||
|
new_key_events[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.key_events = new_key_events
|
||||||
|
|
||||||
|
local new_ges_events = {}
|
||||||
|
if self.ges_events then
|
||||||
|
for k,v in pairs(self.ges_events) do
|
||||||
|
new_ges_events[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.ges_events = new_ges_events
|
||||||
|
|
||||||
|
if not self.dimen then
|
||||||
|
self.dimen = Geom:new{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function InputContainer:paintTo(bb, x, y)
|
||||||
|
self.dimen.x = x
|
||||||
|
self.dimen.y = y
|
||||||
|
if self[1] then
|
||||||
|
if self.vertical_align == "center" then
|
||||||
|
local content_size = self[1]:getSize()
|
||||||
|
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
|
||||||
|
else
|
||||||
|
self[1]:paintTo(bb, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
the following handler handles keypresses and checks if they lead to a command.
|
||||||
|
if this is the case, we retransmit another event within ourselves
|
||||||
|
--]]
|
||||||
|
function InputContainer:onKeyPress(key)
|
||||||
|
for name, seq in pairs(self.key_events) do
|
||||||
|
if not seq.is_inactive then
|
||||||
|
for _, oneseq in ipairs(seq) do
|
||||||
|
if key:match(oneseq) then
|
||||||
|
local eventname = seq.event or name
|
||||||
|
return self:handleEvent(Event:new(eventname, seq.args, key))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function InputContainer:onGesture(ev)
|
||||||
|
for name, gsseq in pairs(self.ges_events) do
|
||||||
|
for _, gs_range in ipairs(gsseq) do
|
||||||
|
--DEBUG("gs_range", gs_range)
|
||||||
|
if gs_range:match(ev) then
|
||||||
|
local eventname = gsseq.event or name
|
||||||
|
return self:handleEvent(Event:new(eventname, gsseq.args, ev))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return InputContainer
|
@ -0,0 +1,17 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
LeftContainer aligns its content (1 widget) at the left of its own dimensions
|
||||||
|
--]]
|
||||||
|
local LeftContainer = WidgetContainer:new()
|
||||||
|
|
||||||
|
function LeftContainer:paintTo(bb, x, y)
|
||||||
|
local contentSize = self[1]:getSize()
|
||||||
|
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
||||||
|
-- throw error? paint to scrap buffer and blit partially?
|
||||||
|
-- for now, we ignore this
|
||||||
|
end
|
||||||
|
self[1]:paintTo(bb, x , y + math.floor((self.dimen.h - contentSize.h)/2))
|
||||||
|
end
|
||||||
|
|
||||||
|
return LeftContainer
|
@ -0,0 +1,19 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
RightContainer aligns its content (1 widget) at the right of its own dimensions
|
||||||
|
--]]
|
||||||
|
local RightContainer = WidgetContainer:new()
|
||||||
|
|
||||||
|
function RightContainer:paintTo(bb, x, y)
|
||||||
|
local contentSize = self[1]:getSize()
|
||||||
|
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
|
||||||
|
-- throw error? paint to scrap buffer and blit partially?
|
||||||
|
-- for now, we ignore this
|
||||||
|
end
|
||||||
|
self[1]:paintTo(bb,
|
||||||
|
x + (self.dimen.w - contentSize.w),
|
||||||
|
y + math.floor((self.dimen.h - contentSize.h)/2))
|
||||||
|
end
|
||||||
|
|
||||||
|
return RightContainer
|
@ -0,0 +1,42 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
an UnderlineContainer is a WidgetContainer that is able to paint
|
||||||
|
a line under its child node
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local UnderlineContainer = WidgetContainer:new{
|
||||||
|
linesize = 2,
|
||||||
|
padding = 1,
|
||||||
|
color = 0,
|
||||||
|
vertical_align = "top",
|
||||||
|
}
|
||||||
|
|
||||||
|
function UnderlineContainer:getSize()
|
||||||
|
return self:getContentSize()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UnderlineContainer:getContentSize()
|
||||||
|
local contentSize = self[1]:getSize()
|
||||||
|
return Geom:new{
|
||||||
|
w = contentSize.w,
|
||||||
|
h = contentSize.h + self.linesize + self.padding
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function UnderlineContainer:paintTo(bb, x, y)
|
||||||
|
local container_size = self:getSize()
|
||||||
|
local content_size = self:getContentSize()
|
||||||
|
local p_y = y
|
||||||
|
if self.vertical_align == "center" then
|
||||||
|
p_y = math.floor((container_size.h - content_size.h) / 2) + y
|
||||||
|
elseif self.vertical_align == "bottom" then
|
||||||
|
p_y = (container_size.h - content_size.h) + y
|
||||||
|
end
|
||||||
|
self[1]:paintTo(bb, x, p_y)
|
||||||
|
bb:paintRect(x, y + container_size.h - self.linesize,
|
||||||
|
container_size.w, self.linesize, self.color)
|
||||||
|
end
|
||||||
|
|
||||||
|
return UnderlineContainer
|
@ -0,0 +1,70 @@
|
|||||||
|
local Geom = require("ui/geometry")
|
||||||
|
local Widget = require("ui/widget/widget")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
WidgetContainer is a container for another Widget
|
||||||
|
--]]
|
||||||
|
local WidgetContainer = Widget:new()
|
||||||
|
|
||||||
|
function WidgetContainer:init()
|
||||||
|
if not self.dimen then
|
||||||
|
self.dimen = Geom:new{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function WidgetContainer:getSize()
|
||||||
|
if self.dimen then
|
||||||
|
-- fixed size
|
||||||
|
return self.dimen
|
||||||
|
elseif self[1] then
|
||||||
|
-- return size of first child widget
|
||||||
|
return self[1]:getSize()
|
||||||
|
else
|
||||||
|
return Geom:new{ w = 0, h = 0 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
delete all child widgets
|
||||||
|
--]]
|
||||||
|
function WidgetContainer:clear()
|
||||||
|
while table.remove(self) do end
|
||||||
|
end
|
||||||
|
|
||||||
|
function WidgetContainer:paintTo(bb, x, y)
|
||||||
|
-- default to pass request to first child widget
|
||||||
|
if self[1] then
|
||||||
|
return self[1]:paintTo(bb, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function WidgetContainer:propagateEvent(event)
|
||||||
|
-- propagate to children
|
||||||
|
for _, widget in ipairs(self) do
|
||||||
|
if widget:handleEvent(event) then
|
||||||
|
-- stop propagating when an event handler returns true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Containers will pass events to children or react on them themselves
|
||||||
|
--]]
|
||||||
|
function WidgetContainer:handleEvent(event)
|
||||||
|
if not self:propagateEvent(event) then
|
||||||
|
-- call our own standard event handler
|
||||||
|
return Widget.handleEvent(self, event)
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function WidgetContainer:free()
|
||||||
|
for _, widget in ipairs(self) do
|
||||||
|
if widget.free then widget:free() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return WidgetContainer
|
@ -0,0 +1,24 @@
|
|||||||
|
--[[
|
||||||
|
The EventListener is an interface that handles events
|
||||||
|
|
||||||
|
EventListeners have a rudimentary event handler/dispatcher that
|
||||||
|
will call a method "onEventName" for an event with name
|
||||||
|
"EventName"
|
||||||
|
--]]
|
||||||
|
local EventListener = {}
|
||||||
|
|
||||||
|
function EventListener:new(o)
|
||||||
|
local o = o or {}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
if o.init then o:init() end
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function EventListener:handleEvent(event)
|
||||||
|
if self[event.handler] then
|
||||||
|
return self[event.handler](self, unpack(event.args))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return EventListener
|
@ -0,0 +1,29 @@
|
|||||||
|
local TextWidget = require("ui/widget/textwidget")
|
||||||
|
local RenderText = require("ui/rendertext")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
local Screen = require("ui/screen")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
FixedTextWidget
|
||||||
|
--]]
|
||||||
|
local FixedTextWidget = TextWidget:new{}
|
||||||
|
|
||||||
|
function FixedTextWidget:getSize()
|
||||||
|
local tsize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
|
||||||
|
if not tsize then
|
||||||
|
return Geom:new{}
|
||||||
|
end
|
||||||
|
self._length = tsize.x
|
||||||
|
self._height = self.face.size
|
||||||
|
return Geom:new{
|
||||||
|
w = self._length,
|
||||||
|
h = self._height,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function FixedTextWidget:paintTo(bb, x, y)
|
||||||
|
RenderText:renderUtf8Text(bb, x, y+self._height, self.face, self.text,
|
||||||
|
true, self.bgcolor, self.fgcolor)
|
||||||
|
end
|
||||||
|
|
||||||
|
return FixedTextWidget
|
@ -1,172 +0,0 @@
|
|||||||
require "ui/widget/container"
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
A Layout widget that puts objects besides each others
|
|
||||||
--]]
|
|
||||||
HorizontalGroup = WidgetContainer:new{
|
|
||||||
align = "center",
|
|
||||||
_size = nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
function HorizontalGroup:getSize()
|
|
||||||
if not self._size then
|
|
||||||
self._size = { w = 0, h = 0 }
|
|
||||||
self._offsets = { }
|
|
||||||
for i, widget in ipairs(self) do
|
|
||||||
local w_size = widget:getSize()
|
|
||||||
self._offsets[i] = {
|
|
||||||
x = self._size.w,
|
|
||||||
y = w_size.h
|
|
||||||
}
|
|
||||||
self._size.w = self._size.w + w_size.w
|
|
||||||
if w_size.h > self._size.h then
|
|
||||||
self._size.h = w_size.h
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return self._size
|
|
||||||
end
|
|
||||||
|
|
||||||
function HorizontalGroup:paintTo(bb, x, y)
|
|
||||||
local size = self:getSize()
|
|
||||||
|
|
||||||
for i, widget in ipairs(self) do
|
|
||||||
if self.align == "center" then
|
|
||||||
widget:paintTo(bb,
|
|
||||||
x + self._offsets[i].x,
|
|
||||||
y + math.floor((size.h - self._offsets[i].y) / 2))
|
|
||||||
elseif self.align == "top" then
|
|
||||||
widget:paintTo(bb, x + self._offsets[i].x, y)
|
|
||||||
elseif self.align == "bottom" then
|
|
||||||
widget:paintTo(bb, x + self._offsets[i].x, y + size.h - self._offsets[i].y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function HorizontalGroup:clear()
|
|
||||||
self:free()
|
|
||||||
WidgetContainer.clear(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
function HorizontalGroup:resetLayout()
|
|
||||||
self._size = nil
|
|
||||||
self._offsets = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function HorizontalGroup:free()
|
|
||||||
self:resetLayout()
|
|
||||||
WidgetContainer.free(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
A Layout widget that puts objects under each other
|
|
||||||
--]]
|
|
||||||
VerticalGroup = WidgetContainer:new{
|
|
||||||
align = "center",
|
|
||||||
_size = nil,
|
|
||||||
_offsets = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function VerticalGroup:getSize()
|
|
||||||
if not self._size then
|
|
||||||
self._size = { w = 0, h = 0 }
|
|
||||||
self._offsets = { }
|
|
||||||
for i, widget in ipairs(self) do
|
|
||||||
local w_size = widget:getSize()
|
|
||||||
self._offsets[i] = {
|
|
||||||
x = w_size.w,
|
|
||||||
y = self._size.h,
|
|
||||||
}
|
|
||||||
self._size.h = self._size.h + w_size.h
|
|
||||||
if w_size.w > self._size.w then
|
|
||||||
self._size.w = w_size.w
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return self._size
|
|
||||||
end
|
|
||||||
|
|
||||||
function VerticalGroup:paintTo(bb, x, y)
|
|
||||||
local size = self:getSize()
|
|
||||||
|
|
||||||
for i, widget in ipairs(self) do
|
|
||||||
if self.align == "center" then
|
|
||||||
widget:paintTo(bb,
|
|
||||||
x + math.floor((size.w - self._offsets[i].x) / 2),
|
|
||||||
y + self._offsets[i].y)
|
|
||||||
elseif self.align == "left" then
|
|
||||||
widget:paintTo(bb, x, y + self._offsets[i].y)
|
|
||||||
elseif self.align == "right" then
|
|
||||||
widget:paintTo(bb,
|
|
||||||
x + size.w - self._offsets[i].x,
|
|
||||||
y + self._offsets[i].y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function VerticalGroup:clear()
|
|
||||||
self:free()
|
|
||||||
WidgetContainer.clear(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
function VerticalGroup:resetLayout()
|
|
||||||
self._size = nil
|
|
||||||
self._offsets = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function VerticalGroup:free()
|
|
||||||
self:resetLayout()
|
|
||||||
WidgetContainer.free(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
A Layout widget that puts objects above each other
|
|
||||||
--]]
|
|
||||||
OverlapGroup = WidgetContainer:new{
|
|
||||||
_size = nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
function OverlapGroup:getSize()
|
|
||||||
if not self._size then
|
|
||||||
self._size = {w = 0, h = 0}
|
|
||||||
self._offsets = { x = math.huge, y = math.huge }
|
|
||||||
for i, widget in ipairs(self) do
|
|
||||||
local w_size = widget:getSize()
|
|
||||||
if self._size.h < w_size.h then
|
|
||||||
self._size.h = w_size.h
|
|
||||||
end
|
|
||||||
if self._size.w < w_size.w then
|
|
||||||
self._size.w = w_size.w
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.dimen.w then
|
|
||||||
self._size.w = self.dimen.w
|
|
||||||
end
|
|
||||||
if self.dimen.h then
|
|
||||||
self._size.h = self.dimen.h
|
|
||||||
end
|
|
||||||
|
|
||||||
return self._size
|
|
||||||
end
|
|
||||||
|
|
||||||
function OverlapGroup:paintTo(bb, x, y)
|
|
||||||
local size = self:getSize()
|
|
||||||
|
|
||||||
for i, wget in ipairs(self) do
|
|
||||||
local wget_size = wget:getSize()
|
|
||||||
if wget.align == "right" then
|
|
||||||
wget:paintTo(bb, x+size.w-wget_size.w, y)
|
|
||||||
elseif wget.align == "center" then
|
|
||||||
wget:paintTo(bb, x+math.floor((size.w-wget_size.w)/2), y)
|
|
||||||
else
|
|
||||||
-- default to left
|
|
||||||
wget:paintTo(bb, x, y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
A Layout widget that puts objects besides each others
|
||||||
|
--]]
|
||||||
|
local HorizontalGroup = WidgetContainer:new{
|
||||||
|
align = "center",
|
||||||
|
_size = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function HorizontalGroup:getSize()
|
||||||
|
if not self._size then
|
||||||
|
self._size = { w = 0, h = 0 }
|
||||||
|
self._offsets = { }
|
||||||
|
for i, widget in ipairs(self) do
|
||||||
|
local w_size = widget:getSize()
|
||||||
|
self._offsets[i] = {
|
||||||
|
x = self._size.w,
|
||||||
|
y = w_size.h
|
||||||
|
}
|
||||||
|
self._size.w = self._size.w + w_size.w
|
||||||
|
if w_size.h > self._size.h then
|
||||||
|
self._size.h = w_size.h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self._size
|
||||||
|
end
|
||||||
|
|
||||||
|
function HorizontalGroup:paintTo(bb, x, y)
|
||||||
|
local size = self:getSize()
|
||||||
|
|
||||||
|
for i, widget in ipairs(self) do
|
||||||
|
if self.align == "center" then
|
||||||
|
widget:paintTo(bb,
|
||||||
|
x + self._offsets[i].x,
|
||||||
|
y + math.floor((size.h - self._offsets[i].y) / 2))
|
||||||
|
elseif self.align == "top" then
|
||||||
|
widget:paintTo(bb, x + self._offsets[i].x, y)
|
||||||
|
elseif self.align == "bottom" then
|
||||||
|
widget:paintTo(bb, x + self._offsets[i].x, y + size.h - self._offsets[i].y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function HorizontalGroup:clear()
|
||||||
|
self:free()
|
||||||
|
WidgetContainer.clear(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function HorizontalGroup:resetLayout()
|
||||||
|
self._size = nil
|
||||||
|
self._offsets = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function HorizontalGroup:free()
|
||||||
|
self:resetLayout()
|
||||||
|
WidgetContainer.free(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
return HorizontalGroup
|
@ -0,0 +1,14 @@
|
|||||||
|
local Widget = require("ui/widget/widget")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Dummy Widget that reserves horizontal space
|
||||||
|
--]]
|
||||||
|
local HorizontalSpan = Widget:new{
|
||||||
|
width = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
function HorizontalSpan:getSize()
|
||||||
|
return {w = self.width, h = 0}
|
||||||
|
end
|
||||||
|
|
||||||
|
return HorizontalSpan
|
@ -0,0 +1,51 @@
|
|||||||
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
A Layout widget that puts objects above each other
|
||||||
|
--]]
|
||||||
|
local OverlapGroup = WidgetContainer:new{
|
||||||
|
_size = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function OverlapGroup:getSize()
|
||||||
|
if not self._size then
|
||||||
|
self._size = {w = 0, h = 0}
|
||||||
|
self._offsets = { x = math.huge, y = math.huge }
|
||||||
|
for i, widget in ipairs(self) do
|
||||||
|
local w_size = widget:getSize()
|
||||||
|
if self._size.h < w_size.h then
|
||||||
|
self._size.h = w_size.h
|
||||||
|
end
|
||||||
|
if self._size.w < w_size.w then
|
||||||
|
self._size.w = w_size.w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.dimen.w then
|
||||||
|
self._size.w = self.dimen.w
|
||||||
|
end
|
||||||
|
if self.dimen.h then
|
||||||
|
self._size.h = self.dimen.h
|
||||||
|
end
|
||||||
|
|
||||||
|
return self._size
|
||||||
|
end
|
||||||
|
|
||||||
|
function OverlapGroup:paintTo(bb, x, y)
|
||||||
|
local size = self:getSize()
|
||||||
|
|
||||||
|
for i, wget in ipairs(self) do
|
||||||
|
local wget_size = wget:getSize()
|
||||||
|
if wget.align == "right" then
|
||||||
|
wget:paintTo(bb, x+size.w-wget_size.w, y)
|
||||||
|
elseif wget.align == "center" then
|
||||||
|
wget:paintTo(bb, x+math.floor((size.w-wget_size.w)/2), y)
|
||||||
|
else
|
||||||
|
-- default to left
|
||||||
|
wget:paintTo(bb, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return OverlapGroup
|
@ -0,0 +1,15 @@
|
|||||||
|
local Widget = require("ui/widget/widget")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Dummy Widget that reserves vertical and horizontal space
|
||||||
|
]]
|
||||||
|
local RectSpan = Widget:new{
|
||||||
|
width = 0,
|
||||||
|
hright = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
function RectSpan:getSize()
|
||||||
|
return {w = self.width, h = self.height}
|
||||||
|
end
|
||||||
|
|
||||||
|
return RectSpan
|
@ -0,0 +1,80 @@
|
|||||||
|
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||||
|
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||||
|
local VerticalScrollBar = require("ui/widget/verticalscrollbar")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
local GestureRange = require("ui/gesturerange")
|
||||||
|
local UIManager = require("ui/uimanager")
|
||||||
|
local Screen = require("ui/screen")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Text widget with vertical scroll bar
|
||||||
|
--]]
|
||||||
|
local ScrollTextWidget = InputContainer:new{
|
||||||
|
text = nil,
|
||||||
|
face = nil,
|
||||||
|
bgcolor = 0.0, -- [0.0, 1.0]
|
||||||
|
fgcolor = 1.0, -- [0.0, 1.0]
|
||||||
|
width = 400,
|
||||||
|
height = 20,
|
||||||
|
scroll_bar_width = Screen:scaleByDPI(6),
|
||||||
|
text_scroll_span = Screen:scaleByDPI(6),
|
||||||
|
dialog = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
function ScrollTextWidget:init()
|
||||||
|
self.text_widget = TextBoxWidget:new{
|
||||||
|
text = self.text,
|
||||||
|
face = self.face,
|
||||||
|
bgcolor = self.bgcolor,
|
||||||
|
fgcolor = self.fgcolor,
|
||||||
|
width = self.width - self.scroll_bar_width - self.text_scroll_span,
|
||||||
|
height = self.height
|
||||||
|
}
|
||||||
|
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 = Screen:scaleByDPI(6),
|
||||||
|
height = self.height,
|
||||||
|
}
|
||||||
|
local horizontal_group = HorizontalGroup:new{}
|
||||||
|
table.insert(horizontal_group, self.text_widget)
|
||||||
|
table.insert(horizontal_group, HorizontalSpan:new{width = Screen:scaleByDPI(6)})
|
||||||
|
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 = {
|
||||||
|
Swipe = {
|
||||||
|
GestureRange:new{
|
||||||
|
ges = "swipe",
|
||||||
|
range = self.dimen,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScrollTextWidget:updateScrollBar(text)
|
||||||
|
local virtual_line_num = text:getVirtualLineNum()
|
||||||
|
local visible_line_count = text:getVisLineCount()
|
||||||
|
local all_line_count = text:getAllLineCount()
|
||||||
|
self.v_scroll_bar:set(
|
||||||
|
(virtual_line_num - 1) / all_line_count,
|
||||||
|
(virtual_line_num - 1 + visible_line_count) / all_line_count
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScrollTextWidget:onSwipe(arg, ges)
|
||||||
|
if ges.direction == "north" then
|
||||||
|
self.text_widget:scrollDown()
|
||||||
|
self:updateScrollBar(self.text_widget)
|
||||||
|
elseif ges.direction == "south" then
|
||||||
|
self.text_widget:scrollUp()
|
||||||
|
self:updateScrollBar(self.text_widget)
|
||||||
|
end
|
||||||
|
UIManager:setDirty(self.dialog, "partial")
|
||||||
|
return true
|
||||||
|
end
|
@ -1,27 +0,0 @@
|
|||||||
require "ui/widget/base"
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Dummy Widget that reserves horizontal space
|
|
||||||
--]]
|
|
||||||
HorizontalSpan = Widget:new{
|
|
||||||
width = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
function HorizontalSpan:getSize()
|
|
||||||
return {w = self.width, h = 0}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Dummy Widget that reserves vertical space
|
|
||||||
--]]
|
|
||||||
VerticalSpan = Widget:new{
|
|
||||||
width = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
function VerticalSpan:getSize()
|
|
||||||
return {w = 0, h = self.width}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
local Widget = require("ui/widget/widget")
|
||||||
|
local Screen = require("ui/screen")
|
||||||
|
local RenderText = require("ui/rendertext")
|
||||||
|
local Geom = require("ui/geometry")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
A TextWidget puts a string on a single line
|
||||||
|
--]]
|
||||||
|
local TextWidget = Widget:new{
|
||||||
|
text = nil,
|
||||||
|
face = nil,
|
||||||
|
bgcolor = 0.0, -- [0.0, 1.0]
|
||||||
|
fgcolor = 1.0, -- [0.0, 1.0]
|
||||||
|
_bb = nil,
|
||||||
|
_length = 0,
|
||||||
|
_height = 0,
|
||||||
|
_maxlength = 1200,
|
||||||
|
}
|
||||||
|
|
||||||
|
--function TextWidget:_render()
|
||||||
|
--local h = self.face.size * 1.3
|
||||||
|
--self._bb = Blitbuffer.new(self._maxlength, h)
|
||||||
|
--self._length = RenderText:renderUtf8Text(self._bb, 0, h*0.8, self.face, self.text, self.color)
|
||||||
|
--end
|
||||||
|
|
||||||
|
function TextWidget:getSize()
|
||||||
|
--if not self._bb then
|
||||||
|
--self:_render()
|
||||||
|
--end
|
||||||
|
--return { w = self._length, h = self._bb:getHeight() }
|
||||||
|
local tsize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
|
||||||
|
if not tsize then
|
||||||
|
return Geom:new{}
|
||||||
|
end
|
||||||
|
self._length = tsize.x
|
||||||
|
self._height = self.face.size * 1.5
|
||||||
|
return Geom:new{
|
||||||
|
w = self._length,
|
||||||
|
h = self._height,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function TextWidget:paintTo(bb, x, y)
|
||||||
|
--if not self._bb then
|
||||||
|
--self:_render()
|
||||||
|
--end
|
||||||
|
--bb:blitFrom(self._bb, x, y, 0, 0, self._length, self._bb:getHeight())
|
||||||
|
--@TODO Don't use kerning for monospaced fonts. (houqp)
|
||||||
|
RenderText:renderUtf8Text(bb, x, y+self._height*0.7, self.face, self.text,
|
||||||
|
true, self.bgcolor, self.fgcolor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TextWidget:free()
|
||||||
|
if self._bb then
|
||||||
|
self._bb:free()
|
||||||
|
self._bb = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TextWidget
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue