You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koreader/frontend/ui/widget/buttonprogresswidget.lua

284 lines
10 KiB
Lua

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

local Blitbuffer = require("ffi/blitbuffer")
local Button = require("ui/widget/button")
local Device = require("device")
local Geom = require("ui/geometry")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
local InputContainer = require("ui/widget/container/inputcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local Size = require("ui/size")
local UIManager = require("ui/uimanager")
local _ = require("gettext")
local Screen = Device.screen
local ButtonProgressWidget = InputContainer:new{
width = Screen:scaleBySize(216),
height = Size.item.height_default,
padding = Size.padding.small,
font_face = "cfont",
font_size = 16,
enabled = true,
num_buttons = 2,
position = 1,
default_position = nil,
thin_grey_style = false, -- default to black
fine_tune = false, -- no -/+ buttons on the extremities by default
more_options = false, -- no "⋮" button
}
function ButtonProgressWidget:init()
self.buttonprogress_frame = FrameContainer:new{
background = Blitbuffer.COLOR_WHITE,
color = Blitbuffer.COLOR_DARK_GRAY,
radius = Size.radius.window,
bordersize = 0,
padding = self.padding,
dim = not self.enabled,
}
self.buttonprogress_content = HorizontalGroup:new{}
self.horizontal_span_width = 0
if self.fine_tune or self.more_options then
self.horizontal_span = HorizontalSpan:new{
width = Size.margin.fine_tune
}
self.horizontal_span_width = self.horizontal_span.width
end
self:update()
self.buttonprogress_frame[1] = self.buttonprogress_content
self[1] = self.buttonprogress_frame
self.dimen = Geom:new(self.buttonprogress_frame:getSize())
end
function ButtonProgressWidget:update()
self.buttonprogress_content:clear()
local button_margin = Size.margin.tiny
local button_padding = Size.padding.button
local button_bordersize = self.thin_grey_style and Size.border.thin or Size.border.button
local buttons_count = self.num_buttons
local span_count = 0
if self.fine_tune then
buttons_count = buttons_count + 2
span_count = 2
end
if self.more_options then
buttons_count = buttons_count + 1
span_count = span_count + 1
end
local button_width_real = (self.width - span_count * self.horizontal_span_width) / buttons_count - 2*button_padding - 2*button_margin - 2*button_bordersize
local button_width = math.floor(button_width_real)
local button_width_adjust = button_width_real - button_width
local button_width_to_add = 0
-- Minus button on the left
if self.fine_tune then
button_width_to_add = button_width_to_add + button_width_adjust
local margin = button_margin
local extra_border_size = 0
local button = Button:new{
text = "",
radius = 0,
margin = margin,
padding = button_padding,
bordersize = button_bordersize + extra_border_size,
enabled = true,
width = button_width - 2*extra_border_size,
preselect = false,
text_font_face = self.font_face,
text_font_size = self.font_size,
callback = function()
self.callback("-")
self:update()
end,
no_focus = true,
hold_callback = function()
self.hold_callback("-")
end,
}
if self.thin_grey_style then
button.frame.color = Blitbuffer.COLOR_DARK_GRAY
end
table.insert(self.buttonprogress_content, button)
table.insert(self.buttonprogress_content, self.horizontal_span)
end
-- Actual progress bar
for i = 1, self.num_buttons do
button_width_to_add = button_width_to_add + button_width_adjust
local real_button_width = button_width
if button_width_to_add >= 1 then
-- One pixel wider to better align the entire widget
real_button_width = button_width + math.floor(button_width_to_add)
button_width_to_add = button_width_to_add - math.floor(button_width_to_add)
end
local highlighted = i <= self.position
local is_default = i == self.default_position
local margin = button_margin
if self.thin_grey_style and highlighted then
margin = 0 -- moved outside button so it's not inverted
end
local extra_border_size = 0
if not self.thin_grey_style and is_default then
-- make the border a bit bigger on the default button
extra_border_size = Size.border.thin
end
local button = Button:new{
text = "",
radius = 0,
margin = margin,
padding = button_padding,
bordersize = button_bordersize + extra_border_size,
enabled = true,
width = real_button_width - 2*extra_border_size,
preselect = highlighted,
text_font_face = self.font_face,
text_font_size = self.font_size,
callback = function()
self.callback(i)
self.position = i
self:update()
end,
no_focus = true,
hold_callback = function()
self.hold_callback(i)
end,
}
if self.thin_grey_style then
if is_default then
-- use a black border as a discreet visual hint
button.frame.color = Blitbuffer.COLOR_BLACK
else
-- otherwise, gray border, same as the filled
-- button, so looking as if no border
button.frame.color = Blitbuffer.COLOR_DARK_GRAY
end
if highlighted then
-- The button and its frame background will be inverted,
-- so invert the color we want so it gets inverted back
button.frame.background = Blitbuffer.COLOR_DARK_GRAY:invert()
button = FrameContainer:new{ -- add margin back
margin = button_margin,
padding = 0,
bordersize = 0,
button,
}
end
end
table.insert(self.buttonprogress_content, button)
end
-- Plus button on the right
if self.fine_tune then
button_width_to_add = button_width_to_add + button_width_adjust
local real_button_width = button_width
if button_width_to_add >= 1 then
-- One pixel wider to better align the entire widget
real_button_width = button_width + math.floor(button_width_to_add)
button_width_to_add = button_width_to_add - math.floor(button_width_to_add)
end
local margin = button_margin
local extra_border_size = 0
local button = Button:new{
text = "+",
radius = 0,
margin = margin,
padding = button_padding,
bordersize = button_bordersize + extra_border_size,
enabled = true,
width = real_button_width - 2*extra_border_size,
preselect = false,
text_font_face = self.font_face,
text_font_size = self.font_size,
callback = function()
self.callback("+")
self:update()
end,
no_focus = true,
hold_callback = function()
self.hold_callback("+")
end,
}
if self.thin_grey_style then
button.frame.color = Blitbuffer.COLOR_DARK_GRAY
end
table.insert(self.buttonprogress_content, self.horizontal_span)
table.insert(self.buttonprogress_content, button)
end
-- More option button on the right
if self.more_options then
button_width_to_add = button_width_to_add + button_width_adjust
local real_button_width = button_width
if button_width_to_add >= 1 then
-- One pixel wider to better align the entire widget
real_button_width = button_width + math.floor(button_width_to_add)
end
local margin = button_margin
local extra_border_size = 0
local button = Button:new{
text = "",
radius = 0,
margin = margin,
padding = button_padding,
bordersize = button_bordersize + extra_border_size,
enabled = true,
width = real_button_width - 2*extra_border_size,
preselect = false,
text_font_face = self.font_face,
text_font_size = self.font_size,
callback = function()
self.callback("")
self:update()
end,
no_focus = true,
hold_callback = function()
self.hold_callback("")
end,
}
if self.thin_grey_style then
button.frame.color = Blitbuffer.COLOR_DARK_GRAY
end
table.insert(self.buttonprogress_content, self.horizontal_span)
table.insert(self.buttonprogress_content, button)
end
UIManager:setDirty(self.show_parrent, function()
return "ui", self.dimen
end)
end
function ButtonProgressWidget:setPosition(position, default_position)
self.position = position
self.default_position = default_position
self:update()
end
function ButtonProgressWidget:onFocus()
self.buttonprogress_frame.background = Blitbuffer.COLOR_BLACK
return true
end
function ButtonProgressWidget:onUnfocus()
self.buttonprogress_frame.background = Blitbuffer.COLOR_WHITE
return true
end
function ButtonProgressWidget:onTapSelect(arg, gev)
if gev == nil then
self:circlePosition()
end
end
function ButtonProgressWidget:circlePosition()
if self.position then
self.position = self.position+1
if self.position > self.num_buttons then
self.position = 1
end
self.callback(self.position)
self:update()
end
end
return ButtonProgressWidget