diff --git a/frontend/apps/reader/modules/readerstatus.lua b/frontend/apps/reader/modules/readerstatus.lua index 3542be215..31fd0c94a 100644 --- a/frontend/apps/reader/modules/readerstatus.lua +++ b/frontend/apps/reader/modules/readerstatus.lua @@ -1,5 +1,5 @@ local InputContainer = require("ui/widget/container/inputcontainer") -local StatusWidget = require("ui/widget/statuswidget") +local BookStatusWidget = require("ui/widget/bookstatuswidget") local UIManager = require("ui/uimanager") local _ = require("gettext") @@ -42,7 +42,7 @@ function ReaderStatus:addToMainMenu(tab_item_table) end function ReaderStatus:showStatus() - local status_page = StatusWidget:new { + local status_page = BookStatusWidget:new { thumbnail = self.document:getCoverPageImage(), props = self.document:getProps(), document = self.document, diff --git a/frontend/ui/widget/statuswidget.lua b/frontend/ui/widget/bookstatuswidget.lua similarity index 63% rename from frontend/ui/widget/statuswidget.lua rename to frontend/ui/widget/bookstatuswidget.lua index 33a0f5c1d..8a8263448 100644 --- a/frontend/ui/widget/statuswidget.lua +++ b/frontend/ui/widget/bookstatuswidget.lua @@ -3,6 +3,7 @@ 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 OverlapGroup = require("ui/widget/overlapgroup") local VerticalGroup = require("ui/widget/verticalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") local VerticalSpan = require("ui/widget/verticalspan") @@ -38,7 +39,8 @@ local _ = require("gettext") ["status"] = "Reading" ["modified"] = "24.01.2016" },]] -local StatusWidget = InputContainer:new{ +local BookStatusWidget = InputContainer:new{ + padding = Screen:scaleBySize(15), settings = nil, thumbnail = nil, props = nil, @@ -56,7 +58,7 @@ local StatusWidget = InputContainer:new{ } } -function StatusWidget:init() +function BookStatusWidget:init() self.stats.pages = self.document:getPageCount() self:getStatisticsSettings() if self.settings then @@ -86,84 +88,25 @@ function StatusWidget:init() 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 - if self.thumbnail then - thumb = ImageWidget:new{ - image = self.thumbnail, - width = img_width, - height = img_height, - autoscale = false, - } - end - +function BookStatusWidget:showStatus() local screen_width = Screen:getWidth() - - local cover_with_title_and_author_container = CenterContainer:new{ - dimen = Geom:new{ w = screen_width, h = img_height }, + return VerticalGroup:new{ + align = "left", + OverlapGroup:new{ + dimen = Geom:new{ w = screen_width, h = Screen:scaleBySize(30) }, + CloseButton:new{ window = self }, + }, + self:genBookInfoGroup(), + self:genHeader(_("Statistics")), + self:genStatisticsGroup(screen_width), + self:genHeader(_("Review")), + self:genSummaryGroup(screen_width), + self:genHeader(_("Update Status")), + self:generateSwitchGroup(screen_width), } - - 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.view.state.page, --current page - 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) +function BookStatusWidget:getStatDays(stats) if stats and stats.performance_in_pages then local dates = {} for k, v in pairs(stats.performance_in_pages) do @@ -174,129 +117,59 @@ function StatusWidget:getStatDays(stats) return "none" end - -function StatusWidget:getStatHours(stats) +function BookStatusWidget: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) +function BookStatusWidget: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, - } +function BookStatusWidget:genHeader(title) + local width, height = Screen:getWidth(), Screen:scaleBySize(35) - local bold = false - - local titleWidget = TextWidget:new{ + local header_title = TextWidget:new{ text = title, - face = self.large_font_face, - bold = bold, + face = self.medium_font_face, + fgcolor = Blitbuffer.gray(0.4), } - local titleSize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.large_font_face, title, true, bold) - local lineWidth = ((width - titleSize.x) * 0.5) + local padding_span = HorizontalSpan:new{ width = self.padding } + local line_width = (width - header_title:getSize().w) / 2 - self.padding * 2 local line_container = LeftContainer:new{ - dimen = Geom:new{ w = lineWidth, h = height }, + dimen = Geom:new{ w = line_width, h = height }, LineWidget:new{ background = Blitbuffer.gray(0.2), dimen = Geom:new{ - w = lineWidth, + w = line_width, 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"), + return VerticalGroup:new{ + VerticalSpan:new{ width = Screen:scaleBySize(25) }, + HorizontalGroup:new{ + align = "center", + padding_span, + line_container, + padding_span, + header_title, + padding_span, + line_container, + padding_span, }, - args = args, - default_arg = "reading", - values = { - [1] = 1, - [2] = 2, - [3] = 3, - }, - name = "book_status", - alternate = false, - enabled = true, + VerticalSpan:new{ width = Screen:scaleBySize(5) }, } - - 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) +function BookStatusWidget: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) @@ -304,44 +177,7 @@ function StatusWidget:onChangeBookStatus(option_name, option_value) return true end -function StatusWidget:onUpdateNote() - self.summary.note = self.input_note:getText() - self:saveSummary() - return true -end - - -function StatusWidget:saveSummary() - if self.summary then - self.settings:saveSetting("summary", self.summary) - self.settings:flush() - end -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) +function BookStatusWidget:generateRateGroup(width, height, rating) self.stars_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } @@ -350,7 +186,7 @@ function StatusWidget:generateRateGroup(width, height, rating) return self.stars_container end -function StatusWidget:setStar(num) +function BookStatusWidget:setStar(num) --clear previous data self.stars_container:clear() @@ -379,7 +215,106 @@ function StatusWidget:setStar(num) return true end -function StatusWidget:generateStatisticsGroup(width, height, days, average, pages) +function BookStatusWidget:genBookInfoGroup() + local screen_width = Screen:getWidth() + local split_span_width = screen_width * 0.05 + + local img_width, img_height + if Screen:getScreenMode() == "landscape" then + img_width = Screen:scaleBySize(132) + img_height = Screen:scaleBySize(184) + else + img_width = Screen:scaleBySize(132 * 1.5) + img_height = Screen:scaleBySize(184 * 1.5) + end + + local height = img_height + local width = screen_width - split_span_width - img_width + -- title + local book_meta_info_group = VerticalGroup:new{ + align = "center", + VerticalSpan:new{ width = height * 0.2 }, + TextBoxWidget:new{ + text = self.props.title, + width = width, + face = self.medium_font_face, + alignment = "center", + }, + + } + -- author + local text_author = TextWidget:new{ + text = self.props.authors, + face = self.small_font_face, + padding = 2, + } + table.insert(book_meta_info_group, + CenterContainer:new{ + dimen = Geom:new{ w = width, h = text_author:getSize().h }, + text_author + } + ) + -- progress bar + local total_pages = self.document:getPageCount() + local read_percentage = self.view.state.page / total_pages + local progress_bar = ProgressWidget:new{ + width = width * 0.7, + height = Screen:scaleBySize(10), + percentage = read_percentage, + } + table.insert(book_meta_info_group, + CenterContainer:new{ + dimen = Geom:new{ w = width, h = progress_bar:getSize().h }, + progress_bar + } + ) + -- complete text + local text_complete = TextWidget:new{ + text = template(_("%1% Completed"), + string.format("%1.f", read_percentage * 100)), + face = self.small_font_face, + } + table.insert(book_meta_info_group, + CenterContainer:new{ + dimen = Geom:new{ w = width, h = text_complete:getSize().h }, + text_complete + } + ) + -- rating + table.insert(book_meta_info_group, + VerticalSpan:new{ width = Screen:scaleBySize(30) }) + local rateHeight = Screen:scaleBySize(60) + table.insert(book_meta_info_group, + self:generateRateGroup(screen_width, rateHeight, self.summary.rating)) + + -- build the final group + local book_info_group = HorizontalGroup:new{ + align = "top", + HorizontalSpan:new{ width = split_span_width } + } + -- thumbnail + if self.thumbnail then + table.insert(book_info_group, ImageWidget:new{ + image = self.thumbnail, + width = img_width, + height = img_height, + autoscale = false, + }) + end + + table.insert(book_info_group, CenterContainer:new{ + dimen = Geom:new{ w = width, h = height }, + book_meta_info_group, + }) + + return CenterContainer:new{ + dimen = Geom:new{ w = screen_width, h = img_height }, + book_info_group, + } +end + +function BookStatusWidget:genStatisticsGroup(width) + local height = Screen:scaleBySize(60) local statistics_container = CenterContainer:new{ dimen = Geom:new{ w = width, h = height }, } @@ -414,27 +349,26 @@ function StatusWidget:generateStatisticsGroup(width, height, days, average, page } } - local data_group = HorizontalGroup:new{ align = "center", CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ - text = days, + text = self:getStatDays(self.stats), face = self.medium_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ - text = average, + text = self:getStatHours(self.stats), face = self.medium_font_face, }, }, CenterContainer:new{ dimen = Geom:new{ w = tile_width, h = tile_height }, TextWidget:new{ - text = pages, + text = self:getReadPages(self.stats), face = self.medium_font_face, } } @@ -447,82 +381,130 @@ function StatusWidget:generateStatisticsGroup(width, height, days, average, page return statistics_container end -function StatusWidget:generateTitleAuthorProgressGroup(width, height, title, authors, current_page, total_pages) +function BookStatusWidget:genSummaryGroup(width) + local height + if Screen:getScreenMode() == "landscape" then + height = Screen:scaleBySize(60) + else + height = Screen:scaleBySize(130) + end - local title_author_container = CenterContainer:new{ - dimen = Geom:new{ w = width, h = height }, + local text_padding = 5 + self.input_note = InputText:new{ + text = self.summary.note, + face = self.medium_font_face, + width = width - self.padding * 3, + height = height * 0.75, + scroll = true, + bordersize = 2, + focused = false, + padding = text_padding, + parent = self, + hint = _("A few words about the book"), } - 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 read_percentage = current_page / total_pages - local progress_height = Screen:scaleBySize(10) - - local progress_bar = ProgressWidget:new{ - width = width * 0.7, - height = progress_height, - percentage = read_percentage, - ticks = {}, - tick_width = 0, - last = total_pages, - } - - table.insert(title_author_progressbar_group, + return VerticalGroup:new{ + VerticalSpan:new{ width = Screen:scaleBySize(5) }, CenterContainer:new{ - dimen = Geom:new{ w = width, h = progress_bar:getSize().h }, - progress_bar + dimen = Geom:new{ w = width, h = height }, + self.input_note } - ) - local text_complete = TextWidget:new{ - text = template(_("%1% Completed"), - string.format("%1.f", read_percentage * 100)), - face = self.small_font_face, + } +end + +function BookStatusWidget:onUpdateNote() + self.summary.note = self.input_note:getText() + self:saveSummary() + return true +end + +function BookStatusWidget:saveSummary() + if self.summary then + self.settings:saveSetting("summary", self.summary) + self.settings:flush() + end +end + +function BookStatusWidget:generateSwitchGroup(width) + local height + if Screen:getScreenMode() == "landscape" then + -- landscape mode + height = Screen:scaleBySize(60) + else + -- portrait mode + height = Screen:scaleBySize(105) + end + + local args = { "complete", "reading", "abandoned" } + + local current_status = self.summary.status + local position = 2 + for k, v in pairs(args) do + if v == curent_status then + position = k + end + end + + local config = { + event = "ChangeBookStatus", + default_value = 2, + args = args, + default_arg = "reading", + toggle = { _("Complete"), _("Reading"), _("Abandoned") }, + values = { 1, 2, 3 }, + name = "book_status", + alternate = false, + enabled = true, } - local progress_bar_text_container = CenterContainer:new{ - dimen = Geom:new{ w = width, h = text_complete:getSize().h }, - text_complete + 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(title_author_progressbar_group, progress_bar_text_container) - table.insert(title_author_container, title_author_progressbar_group) - return title_author_container + return VerticalGroup:new{ + VerticalSpan:new{ width = Screen:scaleBySize(10) }, + CenterContainer:new{ + ignore = "height", + dimen = Geom:new{ w = width, h = height }, + switch, + } + } +end + +function BookStatusWidget: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:onAnyKeyPressed() +function BookStatusWidget:onAnyKeyPressed() return self:onClose() end -function StatusWidget:onClose() +function BookStatusWidget:onClose() self:saveSummary() UIManager:setDirty("all") UIManager:close(self) return true end -function StatusWidget:getStatisticsSettings() +function BookStatusWidget:getStatisticsSettings() if self.settings then local stats = self.settings:readSetting("stats") if stats then @@ -535,7 +517,7 @@ function StatusWidget:getStatisticsSettings() end -function StatusWidget:onSwitchFocus(inputbox) +function BookStatusWidget:onSwitchFocus(inputbox) self.note_dialog = InputDialog:new{ title = "Note", input = self.input_note:getText(), @@ -571,10 +553,9 @@ function StatusWidget:onSwitchFocus(inputbox) UIManager:show(self.note_dialog) end -function StatusWidget:closeInputDialog() +function BookStatusWidget:closeInputDialog() self.note_dialog:onClose() UIManager:close(self.note_dialog) end -return StatusWidget - +return BookStatusWidget diff --git a/frontend/ui/widget/closebutton.lua b/frontend/ui/widget/closebutton.lua index 1a19eebc2..84253c07b 100644 --- a/frontend/ui/widget/closebutton.lua +++ b/frontend/ui/widget/closebutton.lua @@ -14,8 +14,11 @@ Example: local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") +local HorizontalGroup = require("ui/widget/horizontalgroup") +local HorizontalSpan = require("ui/widget/horizontalspan") local TextWidget = require("ui/widget/textwidget") local GestureRange = require("ui/gesturerange") +local Screen = require("device").screen local Font = require("ui/font") local CloseButton = InputContainer:new{ @@ -28,18 +31,24 @@ function CloseButton:init() text = "×", face = Font:getFace("cfont", 32), } + padding_span = HorizontalSpan:new{ width = Screen:scaleBySize(14) } + self[1] = FrameContainer:new{ bordersize = 0, padding = 0, - text_widget + HorizontalGroup:new{ + padding_span, + text_widget, + padding_span, + } } - self.dimen = text_widget:getSize() - self.ges_events.Close = { GestureRange:new{ ges = "tap", - range = self.dimen, + -- x and y coordinates for the widget is only known after the it is + -- drawn. so use callback to get range at runtime. + range = function() return self.dimen end, }, doc = "Tap on close button", }