local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") local CenterContainer = require("ui/widget/container/centercontainer") local LeftContainer = require("ui/widget/container/leftcontainer") local HorizontalGroup = require("ui/widget/horizontalgroup") local VerticalGroup = require("ui/widget/verticalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") local VerticalSpan = require("ui/widget/verticalspan") local InputText = require("ui/widget/inputtext") local ToggleSwitch = require("ui/widget/toggleswitch") local Button = require("ui/widget/button") local ProgressWidget = require("ui/widget/progresswidget") local LineWidget = require("ui/widget/linewidget") local TextWidget = require("ui/widget/textwidget") local ImageWidget = require("ui/widget/imagewidget") local TextBoxWidget = require("ui/widget/textboxwidget") local CloseButton = require("ui/widget/closebutton") local InputDialog = require("ui/widget/inputdialog") local UIManager = require("ui/uimanager") local Geom = require("ui/geometry") local Blitbuffer = require("ffi/blitbuffer") local Screen = require("device").screen local Font = require("ui/font") local TimeVal = require("ui/timeval") local RenderText = require("ui/rendertext") local util = require("util") local _ = require("gettext") --[[ --Save into sdr folder addtional section ["summary"] = { ["rating"] = 5, ["note"] = "Some text", ["status"] = "Reading" ["modified"] = "24.01.2016" },]] local StatusWidget = InputContainer:new{ settings = nil, thumbnail = nil, props = nil, star = {}, summary = { rating = nil, note = nil, status = "", modified = "", }, stats = { total_time_in_sec = 0, performance_in_pages = {}, pages = 0, } } function StatusWidget:init() self.stats.pages = self.document:getPageCount() self:getStatisticsSettings() if self.settings then self.summary = self.settings:readSetting("summary") end self.small_font_face = Font:getFace("ffont", 15) self.medium_font_face = Font:getFace("ffont", 20) self.large_font_face = Font:getFace("ffont", 25) self.star = Button:new{ icon = "resources/icons/stats.star.empty.png", bordersize = 0, radius = 0, margin = 0, enabled = true, show_parent = self, } local statusContainer = FrameContainer:new{ dimen = Screen:getSize(), background = Blitbuffer.COLOR_WHITE, bordersize = 0, padding = 0, self:showStatus(), } self[1] = statusContainer end function StatusWidget:showStatus() local main_group = VerticalGroup:new{ align = "left" } local img_width = Screen:scaleBySize(132 * 1.5) local img_height = Screen:scaleBySize(184 * 1.5) if Screen:getScreenMode() == "landscape" then img_width = Screen:scaleBySize(132) img_height = Screen:scaleBySize(184) end local thumb = nil if self.thumbnail then thumb = ImageWidget:new{ image = self.thumbnail, width = img_width, height = img_height, autoscale = false, } end local screen_width = Screen:getWidth() local cover_with_title_and_author_container = CenterContainer:new{ dimen = Geom:new{ w = screen_width, h = img_height }, } local cover_with_title_and_author_group = HorizontalGroup:new{ align = "top" } local span = HorizontalSpan:new{ width = screen_width * 0.05 } table.insert(cover_with_title_and_author_group, span) if self.thumbnail then table.insert(cover_with_title_and_author_group, thumb) end table.insert(cover_with_title_and_author_group, self:generateTitleAuthorProgressGroup(screen_width - span.width - img_width, img_height, self.props.title, self.props.authors, self.document:getCurrentPage(), self.document:getPageCount())) table.insert(cover_with_title_and_author_container, cover_with_title_and_author_group) --portrait mode local rateHeight = Screen:scaleBySize(60) local statisticsHeight = Screen:scaleBySize(60) local summaryHeight = Screen:scaleBySize(140) local statusHeight = Screen:scaleBySize(105) --landscape mode if Screen:getScreenMode() == "landscape" then summaryHeight = Screen:scaleBySize(70) statusHeight = Screen:scaleBySize(60) end local header_group = HorizontalGroup:new{ align = "center", self:addHeader(screen_width * 0.95, Screen:scaleBySize(15), _("Progress")), CloseButton:new{ window = self } } table.insert(main_group, header_group) table.insert(main_group, cover_with_title_and_author_container) table.insert(main_group, self:addHeader(screen_width, Screen:scaleBySize(25), _("Rate"))) table.insert(main_group, self:generateRateGroup(screen_width, rateHeight, self.summary.rating)) table.insert(main_group, self:addHeader(screen_width, Screen:scaleBySize(35), _("Statistics"))) table.insert(main_group, self:generateStatisticsGroup(screen_width, statisticsHeight, self:getStatDays(self.stats), self:getStatHours(self.stats), self:getReadPages(self.stats))) table.insert(main_group, self:addHeader(screen_width, Screen:scaleBySize(35), _("Review"))) table.insert(main_group, self:generateSummaryGroup(screen_width, summaryHeight, self.summary.note)) table.insert(main_group, self:addHeader(screen_width, Screen:scaleBySize(25), _("Update Status"))) table.insert(main_group, self:generateSwitchGroup(screen_width, statusHeight, self.summary.status)) return main_group end function StatusWidget:getStatDays(stats) if stats and stats.performance_in_pages then local dates = {} for k, v in pairs(stats.performance_in_pages) do dates[os.date("%Y-%m-%d", k)] = "" end return util.tableSize(dates) end return "none" end function StatusWidget:getStatHours(stats) if stats and stats.total_time_in_sec then return util.secondsToClock(stats.total_time_in_sec, false) end return "none" end function StatusWidget:getReadPages(stats) if stats and stats.performance_in_pages and stats.pages then return util.tableSize(stats.performance_in_pages) .. "/" .. stats.pages end return "none" end function StatusWidget:addHeader(width, height, title) local group = HorizontalGroup:new{ align = "center", bordersize = 0, } local bold = false local titleWidget = TextWidget:new{ text = title, face = self.large_font_face, bold = bold, } local titleSize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.large_font_face, title, true, bold) local lineWidth = ((width - titleSize.x) * 0.5) local line_container = LeftContainer:new{ dimen = Geom:new{ w = lineWidth, h = height }, LineWidget:new{ background = Blitbuffer.gray(0.2), dimen = Geom:new{ w = lineWidth, h = 2, } } } local text_container = CenterContainer:new{ dimen = Geom:new{ w = titleSize.x, h = height }, titleWidget, } table.insert(group, line_container) table.insert(group, text_container) table.insert(group, line_container) return group end function StatusWidget:generateSwitchGroup(width, height, book_status) local switch_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } local args = { [1] = "complete", [2] = "reading", [3] = "abandoned", } local position = 2 for k, v in pairs(args) do if v == book_status then position = k end end local config = { event = "ChangeBookStatus", default_value = 2, toggle = { [1] = _("Complete"), [2] = _("Reading"), [3] = _("Abandoned"), }, args = args, default_arg = "reading", values = { [1] = 1, [2] = 2, [3] = 3, }, name = "book_status", alternate = false, enabled = true, } local switch = ToggleSwitch:new{ width = width * 0.6, default_value = config.default_value, name = config.name, name_text = config.name_text, event = config.event, toggle = config.toggle, args = config.args, alternate = config.alternate, default_arg = config.default_arg, values = config.values, enabled = config.enable, config = self, } switch:setPosition(position) table.insert(switch_container, switch) return switch_container end function StatusWidget:onConfigChoose(values, name, event, args, events, position) UIManager:scheduleIn(0.05, function() if values then self:onChangeBookStatus(args, position) end UIManager:setDirty("all") end) end function StatusWidget:onChangeBookStatus(option_name, option_value) local curr_time = TimeVal:now() self.summary.status = option_name[option_value] self.summary.modified = os.date("%Y-%m-%d", curr_time.sec) self:saveSummary() return true end function StatusWidget:onUpdateNote() self.summary.note = self.input_note:getText() self:saveSummary() return true end function StatusWidget:saveSummary() self.settings:saveSetting("summary", self.summary) self.settings:flush() end function StatusWidget:generateSummaryGroup(width, height, text) self.input_note = InputText:new{ text = text, face = self.medium_font_face, width = width * 0.95, height = height * 0.55, scroll = true, focused = false, margin = 5, padding = 0, parent = self, hint = _("A few words about the book"), } local note_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, self.input_note } return note_container end function StatusWidget:generateRateGroup(width, height, rating) self.stars_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } self:setStar(rating) return self.stars_container end function StatusWidget:setStar(num) --clear previous data self.stars_container:clear() local stars_group = HorizontalGroup:new{ align = "center" } if num then self.summary.rating = num self:saveSummary() for i = 1, num do table.insert(stars_group, self.star:new{ icon = "resources/icons/stats.star.full.png", callback = function() self:setStar(i) end }) end else num = 0 end for i = num + 1, 5 do table.insert(stars_group, self.star:new{ callback = function() self:setStar(i) end }) end table.insert(self.stars_container, stars_group) UIManager:setDirty(nil, "partial") return true end function StatusWidget:generateStatisticsGroup(width, height, days, average, pages) local statistics_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } local statistics_group = VerticalGroup:new{ align = "left" } local tile_width = width / 3 local tile_height = height / 2 local titles_group = HorizontalGroup:new{ align = "center", CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = _("Days"), face = self.small_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = _("Time"), face = self.small_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = _("Read pages"), face = self.small_font_face, } } } local data_group = HorizontalGroup:new{ align = "center", CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = days, face = self.medium_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = average, face = self.medium_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ text = pages, face = self.medium_font_face, } } } table.insert(statistics_group, titles_group) table.insert(statistics_group, data_group) table.insert(statistics_container, statistics_group) return statistics_container end function StatusWidget:generateTitleAuthorProgressGroup(width, height, title, authors, current_page, total_pages) local title_author_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } local title_author_progressbar_group = VerticalGroup:new{ align = "center", VerticalSpan:new{ width = height * 0.2 }, TextBoxWidget:new{ text = title, width = width, face = self.medium_font_face, alignment = "center", } } local text_author = TextWidget:new{ text = authors, face = self.small_font_face, padding = 2, } local author_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = text_author:getSize().h }, text_author } table.insert(title_author_progressbar_group, author_container) local progressWidget = ProgressWidget:new{ width = width * 0.7, height = Screen:scaleBySize(10), percentage = current_page / total_pages, ticks = {}, tick_width = 0, last = total_pages, } local progress_bar_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = progressWidget:getSize().h }, progressWidget } table.insert(title_author_progressbar_group, progress_bar_container) local text_complete = TextWidget:new{ text = string.format("%1.f", progressWidget.percentage * 100) .. "% " .. _("Completed"), face = self.small_font_face, } local progress_bar_text_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = text_complete:getSize().h }, text_complete } table.insert(title_author_progressbar_group, progress_bar_text_container) table.insert(title_author_container, title_author_progressbar_group) return title_author_container end function StatusWidget:onAnyKeyPressed() return self:onClose() end function StatusWidget:onClose() self:saveSummary() UIManager:setDirty("all") UIManager:close(self) return true end function StatusWidget:getStatisticsSettings() if self.settings then local stats = self.settings:readSetting("stats") if stats then self.stats.total_time_in_sec = self.stats.total_time_in_sec + stats.total_time_in_sec for k, v in pairs(stats.performance_in_pages) do self.stats.performance_in_pages[k] = v end end end end function StatusWidget:onSwitchFocus(inputbox) self.note_dialog = InputDialog:new{ title = "Note", input = self.input_note:getText(), input_hint = "", input_type = "text", scroll = true, text_height = Screen:scaleBySize(150), buttons = { { { text = _("Cancel"), callback = function() self:closeInputDialog() end, }, { text = _("OK"), callback = function() self.input_note:setText(self.note_dialog:getInputText()) self:closeInputDialog() self:onUpdateNote() end, }, }, }, enter_callback = function() self:closeInputDialog() end, width = Screen:getWidth() * 0.8, height = Screen:getHeight() * 0.2, } self.note_dialog:onShowKeyboard() UIManager:show(self.note_dialog) end function StatusWidget:closeInputDialog() self.note_dialog:onClose() UIManager:close(self.note_dialog) end return StatusWidget