mirror of
https://github.com/koreader/koreader
synced 2024-11-20 03:25:34 +00:00
f05e62c1fb
Lots of code was doing some renderText calls to get the size of some text string, and truncate it to some width if needed, with or without an added ellipsis, before instantiating a TextWidget with that tweaked text string. This PR fixes/adds some properties and methods to TextWidget so all that can be done by it. It makes the calling code simpler, as they don't need to use RenderText directly. (Additionally, when we go at using Harfbuzz for text rendering, we'll just have to update or replace textwidget.lua without the need to update any higher level code.) Also: - RenderText: removed the space added by truncateTextByWidth after the ellipsis, as it doesn't feel needed, and break right alignment of the ellipsis with other texts. - KeyValuePage: fix some subtle size and alignment issues. - NumberPickerWidget: fix font size (provided font size was not used)
263 lines
7.4 KiB
Lua
263 lines
7.4 KiB
Lua
local Blitbuffer = require("ffi/blitbuffer")
|
|
local ButtonTable = require("ui/widget/buttontable")
|
|
local CenterContainer = require("ui/widget/container/centercontainer")
|
|
local CloseButton = require("ui/widget/closebutton")
|
|
local Device = require("device")
|
|
local FrameContainer = require("ui/widget/container/framecontainer")
|
|
local Geom = require("ui/geometry")
|
|
local GestureRange = require("ui/gesturerange")
|
|
local Font = require("ui/font")
|
|
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
|
local InputContainer = require("ui/widget/container/inputcontainer")
|
|
local LineWidget = require("ui/widget/linewidget")
|
|
local NumberPickerWidget = require("ui/widget/numberpickerwidget")
|
|
local OverlapGroup = require("ui/widget/overlapgroup")
|
|
local Size = require("ui/size")
|
|
local TextBoxWidget = require("ui/widget/textboxwidget")
|
|
local TextWidget = require("ui/widget/textwidget")
|
|
local UIManager = require("ui/uimanager")
|
|
local VerticalGroup = require("ui/widget/verticalgroup")
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
|
local _ = require("gettext")
|
|
local Screen = Device.screen
|
|
|
|
local SpinWidget = InputContainer:new{
|
|
title_face = Font:getFace("x_smalltfont"),
|
|
text = nil,
|
|
width = Screen:getWidth() * 0.95,
|
|
height = Screen:getHeight(),
|
|
value_table = nil,
|
|
value_index = nil,
|
|
value = 1,
|
|
value_max = 20,
|
|
value_min = 0,
|
|
value_step = 1,
|
|
value_hold_step = 4,
|
|
ok_text = _("OK"),
|
|
cancel_text = _("Cancel"),
|
|
-- extra button on bottom
|
|
extra_text = nil,
|
|
extra_callback = nil,
|
|
-- set this to see extra default button
|
|
default_value = nil,
|
|
default_text = _("Use default"),
|
|
}
|
|
|
|
function SpinWidget:init()
|
|
self.medium_font_face = Font:getFace("ffont")
|
|
self.light_bar = {}
|
|
self.screen_width = Screen:getWidth()
|
|
self.screen_height = Screen:getHeight()
|
|
if Device:hasKeys() then
|
|
self.key_events = {
|
|
Close = { {"Back"}, doc = "close spin widget" }
|
|
}
|
|
end
|
|
if Device:isTouchDevice() then
|
|
self.ges_events = {
|
|
TapClose = {
|
|
GestureRange:new{
|
|
ges = "tap",
|
|
range = Geom:new{
|
|
w = self.screen_width,
|
|
h = self.screen_height,
|
|
}
|
|
},
|
|
},
|
|
}
|
|
end
|
|
self:update()
|
|
end
|
|
|
|
function SpinWidget:update()
|
|
local value_widget = NumberPickerWidget:new{
|
|
show_parent = self,
|
|
width = self.screen_width * 0.2,
|
|
value = self.value,
|
|
value_table = self.value_table,
|
|
value_index = self.value_index,
|
|
value_min = self.value_min,
|
|
value_max = self.value_max,
|
|
value_step = self.value_step,
|
|
value_hold_step = self.value_hold_step,
|
|
precision = self.precision,
|
|
}
|
|
local value_group = HorizontalGroup:new{
|
|
align = "center",
|
|
value_widget,
|
|
}
|
|
|
|
local close_button = CloseButton:new{ window = self, padding_top = Size.margin.title, }
|
|
local btn_width = close_button:getSize().w + Size.padding.default * 2
|
|
|
|
local value_title = FrameContainer:new{
|
|
padding = Size.padding.default,
|
|
margin = Size.margin.title,
|
|
bordersize = 0,
|
|
TextWidget:new{
|
|
text = self.title_text,
|
|
max_width = self.width - btn_width,
|
|
face = self.title_face,
|
|
bold = true,
|
|
},
|
|
}
|
|
local value_line = LineWidget:new{
|
|
dimen = Geom:new{
|
|
w = self.width,
|
|
h = Size.line.thick,
|
|
}
|
|
}
|
|
local value_bar = OverlapGroup:new{
|
|
dimen = {
|
|
w = self.width,
|
|
h = value_title:getSize().h
|
|
},
|
|
value_title,
|
|
close_button,
|
|
}
|
|
local buttons = {
|
|
{
|
|
{
|
|
text = self.cancel_text,
|
|
callback = function()
|
|
if self.cancel_callback then
|
|
self.value = value_widget:getValue()
|
|
self:cancel_callback(self)
|
|
end
|
|
self:onClose()
|
|
end,
|
|
},
|
|
{
|
|
text = self.ok_text,
|
|
callback = function()
|
|
if self.callback then
|
|
self.value, self.value_index = value_widget:getValue()
|
|
self:callback(self)
|
|
end
|
|
self:onClose()
|
|
end,
|
|
},
|
|
}
|
|
}
|
|
|
|
if self.default_value then
|
|
table.insert(buttons,{
|
|
{
|
|
text = self.default_text,
|
|
callback = function()
|
|
value_widget.value = self.default_value
|
|
value_widget:update()
|
|
end,
|
|
},
|
|
})
|
|
end
|
|
if self.extra_text then
|
|
table.insert(buttons,{
|
|
{
|
|
text = self.extra_text,
|
|
callback = function()
|
|
if self.extra_callback then
|
|
self.value, self.value_index = value_widget:getValue()
|
|
self.extra_callback(self)
|
|
end
|
|
self:onClose()
|
|
end,
|
|
},
|
|
})
|
|
end
|
|
|
|
local ok_cancel_buttons = ButtonTable:new{
|
|
width = self.width - 2*Size.padding.default,
|
|
buttons = buttons,
|
|
zero_sep = true,
|
|
show_parent = self,
|
|
}
|
|
|
|
local vgroup = VerticalGroup:new{
|
|
align = "left",
|
|
value_bar,
|
|
value_line,
|
|
}
|
|
if self.text then
|
|
table.insert(vgroup, FrameContainer:new{
|
|
padding = Size.padding.default,
|
|
margin = Size.margin.small,
|
|
bordersize = 0,
|
|
TextBoxWidget:new{
|
|
text = self.text,
|
|
face = Font:getFace("x_smallinfofont"),
|
|
width = self.width * 0.9,
|
|
}
|
|
})
|
|
end
|
|
table.insert(vgroup, CenterContainer:new{
|
|
dimen = Geom:new{
|
|
w = self.width,
|
|
h = value_group:getSize().h + self.screen_height * 0.1,
|
|
},
|
|
value_group
|
|
})
|
|
table.insert(vgroup, CenterContainer:new{
|
|
dimen = Geom:new{
|
|
w = self.width,
|
|
h = ok_cancel_buttons:getSize().h,
|
|
},
|
|
ok_cancel_buttons
|
|
})
|
|
self.spin_frame = FrameContainer:new{
|
|
radius = Size.radius.window,
|
|
padding = 0,
|
|
margin = 0,
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
vgroup,
|
|
}
|
|
self[1] = WidgetContainer:new{
|
|
align = "center",
|
|
dimen =Geom:new{
|
|
x = 0, y = 0,
|
|
w = self.screen_width,
|
|
h = self.screen_height,
|
|
},
|
|
FrameContainer:new{
|
|
bordersize = 0,
|
|
self.spin_frame,
|
|
}
|
|
}
|
|
UIManager:setDirty(self, function()
|
|
return "ui", self.spin_frame.dimen
|
|
end)
|
|
end
|
|
|
|
function SpinWidget:onCloseWidget()
|
|
UIManager:setDirty(nil, function()
|
|
return "partial", self.spin_frame.dimen
|
|
end)
|
|
return true
|
|
end
|
|
|
|
function SpinWidget:onShow()
|
|
UIManager:setDirty(self, function()
|
|
return "ui", self.spin_frame.dimen
|
|
end)
|
|
return true
|
|
end
|
|
|
|
function SpinWidget:onAnyKeyPressed()
|
|
UIManager:close(self)
|
|
return true
|
|
end
|
|
|
|
function SpinWidget:onTapClose(arg, ges_ev)
|
|
if ges_ev.pos:notIntersectWith(self.spin_frame.dimen) then
|
|
self:onClose()
|
|
end
|
|
return true
|
|
end
|
|
|
|
function SpinWidget:onClose()
|
|
UIManager:close(self)
|
|
return true
|
|
end
|
|
|
|
return SpinWidget
|