diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index 1331c4c01..29fce1ae2 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -74,6 +74,17 @@ function Geom:transformByScale(zx, zy) self:scaleBy(zx, zy) end +--[[ +return size of geom +]]-- +function Geom:sizeof() + if not self.w or not self.h then + return 0 + else + return self.w * self.h + end +end + --[[ enlarges or shrinks dimensions or rectangles @@ -91,7 +102,8 @@ return the outer rectangle that contains both us and a given rectangle works for rectangles, dimensions and points ]]-- function Geom:combine(rect_b) - local combined = Geom:new(self) + local combined = self:copy() + if not rect_b or rect_b:sizeof() == 0 then return combined end if combined.x > rect_b.x then combined.x = rect_b.x end diff --git a/frontend/ui/reader/readerpaging.lua b/frontend/ui/reader/readerpaging.lua index 1b5e7a2f2..2434a28ea 100644 --- a/frontend/ui/reader/readerpaging.lua +++ b/frontend/ui/reader/readerpaging.lua @@ -108,7 +108,7 @@ function ReaderPaging:initGesListener() w = Screen:getWidth(), h = Screen:getHeight(), }, - rate = 4.0, + rate = 5.0, } }, PanRelease = { @@ -244,6 +244,9 @@ end function ReaderPaging:onPanRelease(arg, ges) if self.flipping_mode then self:updateFlippingPage(self.current_page) + else + UIManager.full_refresh = true + UIManager:setDirty(self.view.dialog) end end @@ -516,7 +519,10 @@ function ReaderPaging:onScrollPanRel(diff) end -- update current pageno to the very last part in current view self:gotoPage(self.view.page_states[#self.view.page_states].page, "scrolling") - UIManager:setDirty(self.view.dialog) + + UIManager.waveform_mode = WAVEFORM_MODE_A2 + UIManager.patial_refresh = true + UIManager:setDirty(self.view.dialog, "partial") end function ReaderPaging:onScrollPageRel(diff) diff --git a/frontend/ui/screen.lua b/frontend/ui/screen.lua index 819efd584..c0a7348ff 100644 --- a/frontend/ui/screen.lua +++ b/frontend/ui/screen.lua @@ -72,19 +72,38 @@ function Screen:init() self.cur_rotation_mode = self.native_rotation_mode end -function Screen:refresh(refesh_type) - if self.native_rotation_mode == self.cur_rotation_mode then +function Screen:refresh(refesh_type, waveform_mode, x, y, w, h) + if x then x = x < 0 and 0 or math.floor(x) end + if y then y = y < 0 and 0 or math.floor(y) end + if w then w = w > self.width and self.width or math.ceil(w) end + if h then h = h > self.height and self.height or math.ceil(h) end + if self.native_rotation_mode == self.cur_rotation_mode then self.fb.bb:blitFrom(self.bb, 0, 0, 0, 0, self.width, self.height) elseif self.native_rotation_mode == 0 and self.cur_rotation_mode == 1 then self.fb.bb:blitFromRotate(self.bb, 270) + if x and y and w and h then + x, y = y, self.width - w - x + w, h = h, w + end elseif self.native_rotation_mode == 0 and self.cur_rotation_mode == 3 then self.fb.bb:blitFromRotate(self.bb, 90) + if x and y and w and h then + x, y = self.height - h - y, x + w, h = h, w + end elseif self.native_rotation_mode == 1 and self.cur_rotation_mode == 0 then self.fb.bb:blitFromRotate(self.bb, 90) + if x and y and w and h then + x, y = self.height - h - y, x + w, h = h, w + end elseif self.native_rotation_mode == 1 and self.cur_rotation_mode == 3 then self.fb.bb:blitFromRotate(self.bb, 180) + if x and y and w and h then + x, y = self.width - w - x, self.height - h - y + end end - self.fb:refresh(refesh_type) + self.fb:refresh(refesh_type, waveform_mode, y, x, w, h) end function Screen:getSize() diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 962b95915..88871619b 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -10,18 +10,33 @@ Screen:init() -- initialize the input handling Input:init() +WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears) +WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black +WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing) +WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility +WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity +WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity +WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition +WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition +WAVEFORM_MODE_AUTO = 0x101 -- there is only one instance of this UIManager = { -- change this to set refresh type for next refresh -- defaults to 1 initially and will be set to 1 after each refresh refresh_type = 1, + -- change this to set refresh waveform for next refresh + -- default to WAVEFORM_MODE_GC16 + waveform_mode = WAVEFORM_MODE_GC16, -- force to repaint all the widget is stack, will be reset to false -- after each ui loop repaint_all = false, -- force to do full refresh, will be reset to false -- after each ui loop full_refresh = false, + -- force to do patial refresh, will be reset to false + -- after each ui loop + patial_refresh = false, -- trigger a full refresh when counter reaches FULL_REFRESH_COUNT FULL_REFRESH_COUNT = DRCOUNTMAX, refresh_count = 0, @@ -173,6 +188,7 @@ function UIManager:run() local dirty = false local request_full_refresh = false local force_full_refresh = false + local force_patial_refresh = false for _, widget in ipairs(self._window_stack) do if self.repaint_all or self._dirty[widget.widget] then widget.widget:paintTo(Screen.bb, widget.x, widget.y) @@ -182,6 +198,9 @@ function UIManager:run() if self._dirty[widget.widget] == "full" then force_full_refresh = true end + if self._dirty[widget.widget] == "patial" then + force_patial_refresh = true + end -- and remove from list after painting self._dirty[widget.widget] = nil -- trigger repaint @@ -193,26 +212,41 @@ function UIManager:run() dirty = true force_full_refresh = true end + + if self.patial_refresh then + dirty = true + force_patial_refresh = true + end self.repaint_all = false self.full_refresh = false + self.patial_refresh = false if dirty then - if force_full_refresh then - self.refresh_count = self.FULL_REFRESH_COUNT - 1 - end - if self.refresh_count == self.FULL_REFRESH_COUNT - 1 then + if force_patial_refresh then + self.refresh_type = 1 + elseif force_full_refresh or self.refresh_count == self.FULL_REFRESH_COUNT - 1 then self.refresh_type = 0 else self.refresh_type = 1 end - -- refresh FB - Screen:refresh(self.refresh_type) -- TODO: refresh explicitly only repainted area - -- increase refresh_count only when full refresh is requested or performed - local refresh_increment = (request_full_refresh or self.refresh_type == 0) and 1 or 0 - self.refresh_count = (self.refresh_count + refresh_increment)%self.FULL_REFRESH_COUNT - -- reset refresh_type - self.refresh_type = 1 + --self.waveform_mode = self.fast_refresh and WAVEFORM_MODE_A2 or WAVEFORM_MODE_GC16 + if self.update_region_func then + local update_region = self.update_region_func() + Screen:refresh(self.refresh_type, self.waveform_mode, + update_region.x, update_region.y, + update_region.w, update_region.h) + else + Screen:refresh(self.refresh_type, self.waveform_mode) + end + if self.refresh_type == 0 then + self.refresh_count = 0 + elseif not force_patial_refresh and not force_full_refresh then + self.refresh_count = (self.refresh_count + 1)%self.FULL_REFRESH_COUNT + end + -- reset waveform_mode to WAVEFORM_MODE_GC16 + self.waveform_mode = WAVEFORM_MODE_GC16 + self.update_region_func = nil end self:checkTasks() diff --git a/frontend/ui/widget/config.lua b/frontend/ui/widget/config.lua index da1f116e6..c68fb0f0d 100644 --- a/frontend/ui/widget/config.lua +++ b/frontend/ui/widget/config.lua @@ -37,12 +37,13 @@ end OptionTextItem = InputContainer:new{} function OptionTextItem:init() local text_widget = self[1] - self.dimen = text_widget:getSize() + self[1] = UnderlineContainer:new{ text_widget, padding = self.padding, color = self.color, - } + } + self.dimen = self[1]:getSize() -- we need this table per-instance, so we declare it here if Device:isTouchDevice() then self.ges_events = { @@ -255,7 +256,6 @@ function ConfigOption:init() end end end - if self.options[c].item_text then for d = 1, #self.options[c].item_text do local option_item = nil @@ -421,13 +421,10 @@ function ConfigDialog:init() ------------------------------------------ -- start to set up widget layout --------- ------------------------------------------ - self.config_panel = ConfigPanel:new{ - config_dialog = self, - } self.config_menubar = MenuBar:new{ config_dialog = self, } - self:makeDialog() + self:update() ------------------------------------------ -- start to set up input event callback -- ------------------------------------------ @@ -449,19 +446,17 @@ function ConfigDialog:init() self.key_events.FocusRight = nil end self.key_events.Select = { {"Press"}, doc = _("select current menu item") } - - UIManager:setDirty(self, "partial") end function ConfigDialog:updateConfigPanel(index) - self.panel_index = index - self.config_panel = ConfigPanel:new{ - index = index, - config_dialog = self, - } + end -function ConfigDialog:makeDialog() +function ConfigDialog:update() + self.config_panel = ConfigPanel:new{ + index = self.panel_index, + config_dialog = self, + } self.dialog_frame = FrameContainer:new{ background = 0, VerticalGroup:new{ @@ -474,12 +469,20 @@ function ConfigDialog:makeDialog() dimen = Screen:getSize(), self.dialog_frame, } + UIManager.repaint_all = true end function ConfigDialog:onShowConfigPanel(index) - self:updateConfigPanel(index) - self:makeDialog() - UIManager.repaint_all = true + self.panel_index = index + local orig_dimen = self.dialog_frame and self.dialog_frame.dimen or Geom:new{} + + self:update() + + UIManager.update_region_func = function() + local update_region = self.dialog_frame.dimen:combine(orig_dimen) + DEBUG("update region", update_region) + return update_region + end return true end @@ -487,12 +490,13 @@ function ConfigDialog:onConfigChoice(option_name, option_value) --DEBUG("config option value", option_name, option_value) self.configurable[option_name] = option_value self.ui:handleEvent(Event:new("StartActivityIndicator")) + return true end function ConfigDialog:onConfigEvent(option_event, option_arg) --DEBUG("config option event", option_event, option_arg) self.ui:handleEvent(Event:new(option_event, option_arg)) - self:onShowConfigPanel(self.panel_index) + return true end function ConfigDialog:closeDialog() diff --git a/frontend/ui/widget/container.lua b/frontend/ui/widget/container.lua index a42295803..de0e2d4bc 100644 --- a/frontend/ui/widget/container.lua +++ b/frontend/ui/widget/container.lua @@ -204,16 +204,12 @@ UnderlineContainer = WidgetContainer:new{ } function UnderlineContainer:getSize() - if self.dimen then - return { w = self.dimen.w, h = self.dimen.h } - else - return self:getContentSize() - end + return self:getContentSize() end function UnderlineContainer:getContentSize() local contentSize = self[1]:getSize() - return { + return Geom:new{ w = contentSize.w, h = contentSize.h + self.linesize + self.padding } diff --git a/frontend/ui/widget/dict.lua b/frontend/ui/widget/dict.lua index c939177bb..c2b4ec869 100644 --- a/frontend/ui/widget/dict.lua +++ b/frontend/ui/widget/dict.lua @@ -154,6 +154,7 @@ function DictQuickLookup:update() dimen = Screen:getSize(), self.dict_frame, } + UIManager.repaint_all = true end function DictQuickLookup:isPrevDictAvaiable() @@ -177,8 +178,15 @@ function DictQuickLookup:changeDictionary(index) self.dictionary = self.results[index].dict self.lookupword = self.results[index].word self.definition = self.results[index].definition + + local orig_dimen = self.dict_frame and self.dict_frame.dimen or Geom:new{} self:update() - UIManager.repaint_all = true + + UIManager.update_region_func = function() + local update_region = self.dict_frame.dimen:combine(orig_dimen) + DEBUG("update region", update_region) + return update_region + end end function DictQuickLookup:changeToDefaultDict() diff --git a/koreader-base b/koreader-base index d45c0ac4b..fa55acc48 160000 --- a/koreader-base +++ b/koreader-base @@ -1 +1 @@ -Subproject commit d45c0ac4b1f4801e193d0bc9a6c3759989dec7c2 +Subproject commit fa55acc48b7e48a957ad3b82dd591a9bf91eb645