mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge pull request #141 from houqp/new_ui_code
add a widget that handles line wrapping
This commit is contained in:
19
dialog.lua
19
dialog.lua
@@ -124,17 +124,25 @@ Widget that shows a message and OK/Cancel buttons
|
||||
]]
|
||||
ConfirmBox = FocusManager:new{
|
||||
text = "no text",
|
||||
width = nil,
|
||||
ok_text = "OK",
|
||||
cancel_text = "Cancel",
|
||||
}
|
||||
|
||||
function ConfirmBox:init()
|
||||
-- calculate box width on the fly if not given
|
||||
if not self.width then
|
||||
self.width = G_width - 200
|
||||
end
|
||||
-- build bottons
|
||||
self.key_events.Close = { {{"Home","Back"}}, doc = "cancel" }
|
||||
self.key_events.Select = { {{"Enter","Press"}}, doc = "chose selected option" }
|
||||
|
||||
local ok_button = Button:new{
|
||||
text = "OK"
|
||||
text = self.ok_text,
|
||||
}
|
||||
local cancel_button = Button:new{
|
||||
text = "Cancel",
|
||||
text = self.cancel_text,
|
||||
preselect = true
|
||||
}
|
||||
|
||||
@@ -153,17 +161,18 @@ function ConfirmBox:init()
|
||||
HorizontalSpan:new{ width = 10 },
|
||||
VerticalGroup:new{
|
||||
align = "left",
|
||||
TextWidget:new{
|
||||
TextBoxWidget:new{
|
||||
text = self.text,
|
||||
face = Font:getFace("cfont", 30)
|
||||
face = Font:getFace("cfont", 30),
|
||||
width = self.width,
|
||||
},
|
||||
VerticalSpan:new{ width = 10 },
|
||||
HorizontalGroup:new{
|
||||
ok_button,
|
||||
Widget:new{ dimen = { w = 10, h = 0 } },
|
||||
cancel_button
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
95
widget.lua
95
widget.lua
@@ -193,6 +193,101 @@ function TextWidget:free()
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
A TextWidget that handles long text wrapping
|
||||
]]
|
||||
TextBoxWidget = Widget:new{
|
||||
text = nil,
|
||||
face = nil,
|
||||
color = 15,
|
||||
width = 400, -- in pixels
|
||||
line_height = 0.3, -- in em
|
||||
v_list = nil,
|
||||
_bb = nil,
|
||||
_length = 0,
|
||||
}
|
||||
|
||||
function TextBoxWidget:_wrapGreedyAlg(h_list)
|
||||
local cur_line_width = 0
|
||||
local space_w = sizeUtf8Text(0, G_width, self.face, " ", true).x
|
||||
local cur_line = {}
|
||||
local v_list = {}
|
||||
|
||||
for k,w in ipairs(h_list) do
|
||||
cur_line_width = cur_line_width + w.width
|
||||
if cur_line_width <= self.width then
|
||||
cur_line_width = cur_line_width + space_w
|
||||
table.insert(cur_line, w)
|
||||
else
|
||||
-- wrap to next line
|
||||
table.insert(v_list, cur_line)
|
||||
cur_line = {}
|
||||
cur_line_width = w.width + space_w
|
||||
table.insert(cur_line, w)
|
||||
end
|
||||
end
|
||||
-- handle last line
|
||||
table.insert(v_list, cur_line)
|
||||
|
||||
return v_list
|
||||
end
|
||||
|
||||
function TextBoxWidget:_getVerticalList(alg)
|
||||
-- build horizontal list
|
||||
h_list = {}
|
||||
for w in self.text:gmatch("%S+") do
|
||||
word_box = {}
|
||||
word_box.word = w
|
||||
word_box.width = sizeUtf8Text(0, G_width, self.face, w, true).x
|
||||
table.insert(h_list, word_box)
|
||||
end
|
||||
|
||||
-- @TODO check alg here 25.04 2012 (houqp)
|
||||
-- @TODO replace greedy algorithm with K&P algorithm 25.04 2012 (houqp)
|
||||
return self:_wrapGreedyAlg(h_list)
|
||||
end
|
||||
|
||||
function TextBoxWidget:_render()
|
||||
self.v_list = self:_getVerticalList()
|
||||
local v_list = self.v_list
|
||||
local font_height = self.face.size
|
||||
local line_height_px = self.line_height * font_height
|
||||
local space_w = sizeUtf8Text(0, G_width, self.face, " ", true).x
|
||||
local h = (font_height + line_height_px) * #v_list - line_height_px
|
||||
self._bb = Blitbuffer.new(self.width, h)
|
||||
local y = font_height
|
||||
|
||||
for _,l in ipairs(v_list) do
|
||||
local pen_x = 0
|
||||
for _,w in ipairs(l) do
|
||||
renderUtf8Text(self._bb, pen_x, y, self.face, w.word, true)
|
||||
pen_x = pen_x + w.width + space_w
|
||||
end
|
||||
y = y + line_height_px + font_height
|
||||
end
|
||||
end
|
||||
|
||||
function TextBoxWidget:getSize()
|
||||
if not self._bb then
|
||||
self:_render()
|
||||
end
|
||||
return { w = self.width, h = self._bb:getHeight() }
|
||||
end
|
||||
|
||||
function TextBoxWidget:paintTo(bb, x, y)
|
||||
if not self._bb then
|
||||
self:_render()
|
||||
end
|
||||
bb:blitFrom(self._bb, x, y, 0, 0, self.width, self._bb:getHeight())
|
||||
end
|
||||
|
||||
function TextBoxWidget:free()
|
||||
if self._bb then
|
||||
self._bb:free()
|
||||
self._bb = nil
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
ImageWidget shows an image from a file
|
||||
]]
|
||||
|
||||
10
wtest.lua
10
wtest.lua
@@ -52,7 +52,7 @@ function Clock:schedFunc()
|
||||
self[1] = self:getTextWidget()
|
||||
UIManager:setDirty(self)
|
||||
-- reschedule
|
||||
-- TODO: wait until next real minute shift
|
||||
-- TODO: wait until next real second shift
|
||||
UIManager:scheduleIn(1, function() self:schedFunc() end)
|
||||
end
|
||||
|
||||
@@ -71,7 +71,15 @@ function Clock:getTextWidget()
|
||||
}
|
||||
end
|
||||
|
||||
quiz = ConfirmBox:new{
|
||||
text = "Tell me the truth, isn't it COOL?!",
|
||||
width = 300,
|
||||
ok_text = "Yes, of course.",
|
||||
cancel_text = "No, it's ugly.",
|
||||
}
|
||||
quiz:init()
|
||||
|
||||
UIManager:show(Background:new())
|
||||
UIManager:show(Clock:new())
|
||||
UIManager:show(quiz)
|
||||
UIManager:run()
|
||||
|
||||
Reference in New Issue
Block a user