Calendar view's day view: visual tweaks (#9832)

- Add vertical lines every 10mn
- If today, show an arrow indicator at current time
- Add "Today's timeline" to menu
- Rename badly named self.hour_width, which is a height
reviewable/pr9837/r1
poire-z 1 year ago committed by GitHub
parent 905d5610ba
commit 3ef2811e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -500,6 +500,7 @@ local CalendarDayView = FocusManager:extend{
day_ts = nil,
show_page = 1,
kv_pairs = {},
NB_VERTICAL_SEPARATORS_PER_HOUR = 6 -- one vertical line every 10 minutes
}
function CalendarDayView:init()
@ -677,6 +678,14 @@ function CalendarDayView:init()
end
function CalendarDayView:setupView()
local now = os.time()
self.is_current_day = now >= self.day_ts and now < self.day_ts + 86400
if self.is_current_day then
local date = os.date("*t", now)
self.current_day_hour = date.hour
self.current_hour_second = date.min * 60 + date.sec
end
self.kv_pairs = self.reader_statistics:getBooksFromPeriod(self.day_ts, self.day_ts + 86400)
local seconds_books = self.reader_statistics:getReadingDurationBySecond(self.day_ts)
for _, kv in ipairs(self.kv_pairs) do
@ -712,20 +721,19 @@ function CalendarDayView:setupView()
while time_text_width > self.time_text_width * 0.8 do
font_size = font_size * 0.8
self.time_text_face = Font:getFace("cfont", font_size)
temp_text:free()
temp_text = TextWidget:new{
text = "00:00",
face = self.time_text_face
}
time_text_width = temp_text:getWidth()
end
temp_text:free()
self.pages = #self.kv_pairs <= self.items_per_page+1 and 1 or math.ceil(#self.kv_pairs / self.items_per_page)
self.footer_container[1] = self.pages > 1 and self.page_info or VerticalSpan:new{ w = 0 }
self:_populateBooks()
end
function CalendarDayView:nextPage()
@ -815,7 +823,7 @@ function CalendarDayView:_populateBooks()
else
self.timeline_height = self.timeline_height - Size.padding.default
end
self.hour_width = math.floor(self.timeline_height / 24)
self.hour_height = math.floor(self.timeline_height / 24)
self.timeline_width = self.dimen.w - self.outer_padding - self.time_text_width
if #self.kv_pairs == 0 then
@ -826,42 +834,38 @@ function CalendarDayView:_populateBooks()
})
end
self:refreshTimeline()
end
function CalendarDayView:refreshTimeline()
self.timeline:clear()
for _, v in ipairs(self.kv_pairs) do
if v.checked and v.periods then
local fgcolor, bgcolor = unpack(SPAN_COLORS[(v.book_id % #SPAN_COLORS)+1])
for _, period in ipairs(v.periods) do
local start_hour = math.floor(period.start / 3600)
local finish_hour = math.floor(period.finish / 3600)
for i=0, finish_hour-start_hour do
local start = i==0 and period.start or (start_hour+i) * 3600
if start >= 24 * 3600 then
break
end
local finish = i==finish_hour-start_hour and period.finish or (start_hour+i+1) * 3600 - 1
local span = self:generateSpan(start, finish, bgcolor, fgcolor, v[1])
if span then table.insert(self.timeline, span) end
end
end
end
end
-- Draw decorations first, so read spans can be drawn over them
-- Vertical lines (first, so horizontal lines can override them if we use another color)
for i=0, self.NB_VERTICAL_SEPARATORS_PER_HOUR do
local offset_x = self.time_text_width + self.timeline_width * i / self.NB_VERTICAL_SEPARATORS_PER_HOUR
table.insert(self.timeline, FrameContainer:new{
width = Size.border.thin,
height = 24 * self.hour_height, -- unscaled_size_check: ignore
background = Blitbuffer.COLOR_LIGHT_GRAY,
bordersize = 0,
padding = 0,
overlap_offset = { offset_x, self.timeline_offset },
VerticalSpan:new{ w = 0 }
})
end
-- Hour indicator
for i=0, 23 do
local offset_y = self.timeline_offset + self.hour_width * i
local offset_y = self.timeline_offset + self.hour_height * i
table.insert(self.timeline, FrameContainer:new{
width = self.time_text_width,
height = self.hour_width,
height = self.hour_height,
margin = 0,
padding = 0,
background = Blitbuffer.COLOR_WHITE,
bordersize = 0,
overlap_offset = {0, offset_y},
CenterContainer:new{
dimen = Geom:new{ w = self.time_text_width, h = self.hour_width},
dimen = Geom:new{ w = self.time_text_width, h = self.hour_height},
TextWidget:new{
text = string.format("%02d:00", i),
face = self.time_text_face,
@ -869,20 +873,55 @@ function CalendarDayView:refreshTimeline()
}
}
})
if i ~= 0 then
table.insert(self.timeline, FrameContainer:new{
width = self.timeline_width,
height = Size.border.default,
background = Blitbuffer.COLOR_LIGHT_GRAY,
bordersize = 0,
padding = 0,
overlap_offset = { self.time_text_width, offset_y - Size.border.thin },
CenterContainer:new{
dimen = Geom:new{ w = self.timeline_width, h = Size.border.default },
VerticalSpan:new{ w = 0 }
}
})
end
-- Horizontal lines
for i=0, 24 do
local offset_y = self.timeline_offset + self.hour_height * i
table.insert(self.timeline, FrameContainer:new{
width = self.timeline_width,
height = Size.border.default,
background = Blitbuffer.COLOR_LIGHT_GRAY,
bordersize = 0,
padding = 0,
overlap_offset = { self.time_text_width, offset_y - Size.border.thin },
CenterContainer:new{
dimen = Geom:new{ w = self.timeline_width, h = Size.border.default },
VerticalSpan:new{ w = 0 }
}
})
end
-- Current time arrow indicator
if self.is_current_day then
-- Get the arrow glyph a bit bigger than what it is with the hour indicator font
local font_size = TextWidget:getFontSizeToFitHeight("cfont", self.hour_height*1.1, 0)
local current_time_icon = TextWidget:new{
text = "\u{25B2}", -- black up-pointing triangle
face = Font:getFace("cfont", font_size),
padding = 0,
}
local offset_x = self.time_text_width + math.floor( self.timeline_width * self.current_hour_second / 3600 - current_time_icon:getWidth()/2)
local offset_y = self.timeline_offset + self.hour_height * (self.current_day_hour + 1)
offset_y = offset_y - math.floor(self.hour_height*0.3) -- move it up so it sits over the horizontal line
current_time_icon.overlap_offset = { offset_x, offset_y }
table.insert(self.timeline, current_time_icon)
end
-- Finally, the read books spans
for _, v in ipairs(self.kv_pairs) do
if v.checked and v.periods then
local fgcolor, bgcolor = unpack(SPAN_COLORS[(v.book_id % #SPAN_COLORS)+1])
for _, period in ipairs(v.periods) do
local start_hour = math.floor(period.start / 3600)
local finish_hour = math.floor(period.finish / 3600)
for i=0, finish_hour-start_hour do
local start = i==0 and period.start or (start_hour+i) * 3600
if start >= 24 * 3600 then
break
end
local finish = i==finish_hour-start_hour and period.finish or (start_hour+i+1) * 3600 - 1
local span = self:generateSpan(start, finish, bgcolor, fgcolor, v[1])
if span then table.insert(self.timeline, span) end
end
end
end
end
UIManager:setDirty(self, function()
@ -894,10 +933,10 @@ function CalendarDayView:generateSpan(start, finish, bgcolor, fgcolor, title)
local width = math.floor((finish - start)/3600*self.timeline_width)
if width <= 0 then return end
local start_hour = math.floor(start / 3600)
local offset_y = start_hour * self.hour_width + self.inner_padding + self.timeline_offset
local offset_y = start_hour * self.hour_height + self.inner_padding + self.timeline_offset
local offset_x = self.time_text_width + math.floor((start % 3600) / 3600 * self.timeline_width)
local font_size = TextWidget:getFontSizeToFitHeight("cfont", self.hour_width - 2 * self.inner_padding, 0.3)
local font_size = TextWidget:getFontSizeToFitHeight("cfont", self.hour_height - 2 * self.inner_padding, 0.3)
local min_width = TextWidget:new{
text = "",
face = Font:getFace("cfont", font_size),
@ -905,13 +944,13 @@ function CalendarDayView:generateSpan(start, finish, bgcolor, fgcolor, title)
}:getWidth()
return FrameContainer:new{
width = width,
height = self.hour_width - 2 * self.inner_padding,
height = self.hour_height - 2 * self.inner_padding,
bordersize = Size.border.thin,
overlap_offset = {offset_x, offset_y},
background = bgcolor,
padding = 0.3,
CenterContainer:new{
dimen = Geom:new{ h = self.hour_width - 2 * self.inner_padding, w = width },
dimen = Geom:new{ h = self.hour_height - 2 * self.inner_padding, w = width },
width > min_width and TextWidget:new{
text = title,
face = Font:getFace("cfont", font_size),

@ -1220,6 +1220,13 @@ The max value ensures a page you stay on for a long time (because you fell aslee
self:onShowCalendarView()
end,
},
{
text = _("Today's timeline"),
keep_menu_open = true,
callback = function()
self:onShowCalendarDayView()
end,
},
},
}
end

Loading…
Cancel
Save