From 9c4088a3ac88e07ea5a4810bc7f077b9247a43c0 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Mon, 1 Dec 2014 12:32:27 +0000 Subject: [PATCH 1/4] small change of UIManager:show(): No more automatic refresh This eliminates the API difference between the extra parameters of UIManager:show() and setDirty(). They work the same now. Note that this also eliminates the automatic refresh that took place before when using show() without refresh options. It always refreshed the full screen, which led to too big refresh regions all over the place. Thus, refresh has now explicitly to be asked for, hopefully encouraging to implement it in the widget that gets shown (and is aware about the screen region it covers). Also add an event that is triggered when a widget is closed: CloseWidget. So a widget can implement "onCloseWidget()" to trigger actions upon closing - most commonly, this is a refresh for the area previously taken by the widget. That way, the widget's user does not have to take measures to ensure that the area is refreshed later. --- frontend/ui/uimanager.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 3f0fea5a2..7466d1cf3 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -84,7 +84,7 @@ end -- register & show a widget -- modal widget should be always on the top -- for refreshtype & refreshregion see description of setDirty() -function UIManager:show(widget, x, y, refreshtype, refreshregion) +function UIManager:show(widget, refreshtype, refreshregion, x, y) DEBUG("show widget", widget.id) self._running = true local window = {x = x or 0, y = y or 0, widget = widget} @@ -98,7 +98,7 @@ function UIManager:show(widget, x, y, refreshtype, refreshregion) end end -- and schedule it to be painted - self:setDirty(widget, refreshtype or "partial", refreshregion) + self:setDirty(widget, refreshtype, refreshregion) -- tell the widget that it is shown now widget:handleEvent(Event:new("Show")) -- check if this widget disables double tap gesture @@ -120,6 +120,8 @@ function UIManager:close(widget, refreshtype, refreshregion) local dirty = false for i = #self._window_stack, 1, -1 do if self._window_stack[i].widget == widget then + -- tell the widget that it is closed now + widget:handleEvent(Event:new("CloseWidget")) table.remove(self._window_stack, i) dirty = true elseif self._window_stack[i].widget.disable_double_tap then @@ -207,7 +209,6 @@ function UIManager:setDirty(widget, refreshtype, refreshregion) end end -- handle refresh information - if not refreshtype or refreshtype == "none" then return end if type(refreshtype) == "function" then -- callback, will be issued after painting table.insert(self._refresh_func_stack, refreshtype) From 94ce08937a7ea4384d041c95a075c647f96fb0b5 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Mon, 1 Dec 2014 14:39:41 +0000 Subject: [PATCH 2/4] clean up refreshes This is a larger clean-up of the refresh situation. The general shift is that refreshes are now mainly triggered by the (top-level) widgets when they get shown or closed via UIManager. All refreshes for the widgets when they are in use were handled by themselves before. This adds the case of showing/closing. It is the desired result of not having UIManager:show()/:close() do (full screen) refreshes on its own. --- frontend/apps/opdscatalog/opdscatalog.lua | 11 +++++ .../apps/reader/modules/readercropping.lua | 14 +++++++ .../apps/reader/modules/readerdictionary.lua | 2 +- frontend/apps/reader/modules/readerfont.lua | 2 +- .../apps/reader/modules/readerhighlight.lua | 5 +-- frontend/apps/reader/readerui.lua | 2 +- frontend/ui/screensaver.lua | 5 ++- frontend/ui/widget/bboxwidget.lua | 4 ++ frontend/ui/widget/buttondialog.lua | 12 ++++++ frontend/ui/widget/configdialog.lua | 6 +++ frontend/ui/widget/confirmbox.lua | 11 +++++ frontend/ui/widget/dictquicklookup.lua | 14 +++++++ frontend/ui/widget/infomessage.lua | 21 +++++----- frontend/ui/widget/inputdialog.lua | 14 ++++++- frontend/ui/widget/inputtext.lua | 12 +++--- frontend/ui/widget/linkbox.lua | 10 +++++ frontend/ui/widget/logindialog.lua | 1 - frontend/ui/widget/menu.lua | 16 +++++--- frontend/ui/widget/notification.lua | 19 ++++----- frontend/ui/widget/virtualkeyboard.lua | 40 +++++++++---------- 20 files changed, 159 insertions(+), 62 deletions(-) diff --git a/frontend/apps/opdscatalog/opdscatalog.lua b/frontend/apps/opdscatalog/opdscatalog.lua index d34fe04a7..6b7166b95 100644 --- a/frontend/apps/opdscatalog/opdscatalog.lua +++ b/frontend/apps/opdscatalog/opdscatalog.lua @@ -62,7 +62,18 @@ function OPDSCatalog:init() background = Blitbuffer.COLOR_WHITE, opds_browser, } +end + +function OPDSCatalog:onShow() + UIManager:setDirty(self, function() + return "partial", self[1].dimen + end) +end +function OPDSCatalog:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1].dimen + end) end function OPDSCatalog:showCatalog() diff --git a/frontend/apps/reader/modules/readercropping.lua b/frontend/apps/reader/modules/readercropping.lua index a24174be5..57c65184f 100644 --- a/frontend/apps/reader/modules/readercropping.lua +++ b/frontend/apps/reader/modules/readercropping.lua @@ -64,6 +64,20 @@ function PageCropDialog:init() } end +function PageCropDialog:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1].dimen:combine(self[2].dimen) + end) + return true +end + +function PageCropDialog:onShow() + UIManager:setDirty(self, function() + return "partial", self[1].dimen:combine(self[2].dimen) + end) + return true +end + local ReaderCropping = InputContainer:new{} function ReaderCropping:onPageCrop(mode) diff --git a/frontend/apps/reader/modules/readerdictionary.lua b/frontend/apps/reader/modules/readerdictionary.lua index adc46f92b..2c4bd6ac9 100644 --- a/frontend/apps/reader/modules/readerdictionary.lua +++ b/frontend/apps/reader/modules/readerdictionary.lua @@ -106,7 +106,7 @@ function ReaderDictionary:showDict(word, results, box) -- differentiate between dict and wiki wiki = self.wiki, } - UIManager:show(self.dict_window, nil, nil, "none") + UIManager:show(self.dict_window) end end diff --git a/frontend/apps/reader/modules/readerfont.lua b/frontend/apps/reader/modules/readerfont.lua index d2bfaa2da..ef8cfc362 100644 --- a/frontend/apps/reader/modules/readerfont.lua +++ b/frontend/apps/reader/modules/readerfont.lua @@ -149,7 +149,7 @@ function ReaderFont:onSetFontSize(new_size) UIManager:show(Notification:new{ text = T( _("Font size set to %1."), self.font_size), timeout = 1, - }, nil, nil, "none") + }) self.ui.document:setFontSize(Screen:scaleBySize(new_size)) self.ui:handleEvent(Event:new("UpdatePos")) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 628531087..06af6cb26 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -241,6 +241,7 @@ function ReaderHighlight:onHold(arg, ges) end UIManager:setDirty(self.dialog, "partial") -- TODO: only mark word? + -- Unfortunately, CREngine does not return good coordinates -- UIManager:setDirty(self.dialog, "partial", self.selected_word.sbox) end return true @@ -368,9 +369,7 @@ function ReaderHighlight:onHoldRelease() }, tap_close_callback = function() self:handleEvent(Event:new("Tap")) end, } - UIManager:show(self.highlight_dialog, nil, nil, function() - return "partial", self.highlight_dialog.dimen - end) + UIManager:show(self.highlight_dialog) end return true end diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index b1bffc74a..c23d5d709 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -394,7 +394,7 @@ function ReaderUI:onClose() DEBUG("closing document") self:onCloseDocument() end - UIManager:close(self.dialog) + UIManager:close(self.dialog, "full") -- serialize last used items for later launch Cache:serialize() running_instance = nil diff --git a/frontend/ui/screensaver.lua b/frontend/ui/screensaver.lua index 0bbd38f6d..b8adc2b62 100644 --- a/frontend/ui/screensaver.lua +++ b/frontend/ui/screensaver.lua @@ -128,8 +128,11 @@ function Screensaver:show() -- fallback to suspended message if not self.suspend_msg then self.suspend_msg = InfoMessage:new{ text = _("Suspended") } + UIManager:show(self.suspend_msg) + else + -- refresh whole screen for other types + UIManager:show(self.suspend_msg, "full") end - UIManager:show(self.suspend_msg) end function Screensaver:close() diff --git a/frontend/ui/widget/bboxwidget.lua b/frontend/ui/widget/bboxwidget.lua index 8c1a98ef2..4046613f0 100644 --- a/frontend/ui/widget/bboxwidget.lua +++ b/frontend/ui/widget/bboxwidget.lua @@ -15,6 +15,7 @@ local BBoxWidget = InputContainer:new{ screen_bbox = nil, linesize = 2, fine_factor = 10, + dimen = Geom:new(), } function BBoxWidget:init() @@ -55,6 +56,9 @@ function BBoxWidget:getSize() end function BBoxWidget:paintTo(bb, x, y) + self.dimen = self.view.dimen:copy() + self.dimen.x, self.dimen.y = x, y + -- As getScreenBBox uses view states, screen_bbox initialization is postponed. self.screen_bbox = self.screen_bbox or self:getScreenBBox(self.page_bbox) local bbox = self.screen_bbox diff --git a/frontend/ui/widget/buttondialog.lua b/frontend/ui/widget/buttondialog.lua index f5b6d7dd1..02df4d6c1 100644 --- a/frontend/ui/widget/buttondialog.lua +++ b/frontend/ui/widget/buttondialog.lua @@ -50,6 +50,18 @@ function ButtonDialog:init() } end +function ButtonDialog:onShow() + UIManager:setDirty(self, function() + return "partial", self[1][1].dimen + end) +end + +function ButtonDialog:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1][1].dimen + end) +end + function ButtonDialog:onTapClose() UIManager:close(self) if self.tap_close_callback then diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index 9d3cdff3a..63f0aeb9d 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -520,6 +520,12 @@ function ConfigDialog:update() } end +function ConfigDialog:onCloseWidget() + UIManager:setDirty("all", function() + return "partial", self.dialog_frame.dimen + end) +end + function ConfigDialog:onShowConfigPanel(index) self.panel_index = index local old_dimen = self.dialog_frame.dimen and self.dialog_frame.dimen:copy() diff --git a/frontend/ui/widget/confirmbox.lua b/frontend/ui/widget/confirmbox.lua index 856e62f08..df1589a2a 100644 --- a/frontend/ui/widget/confirmbox.lua +++ b/frontend/ui/widget/confirmbox.lua @@ -87,7 +87,18 @@ function ConfirmBox:init() } } } +end + +function ConfirmBox:onShow() + UIManager:setDirty(self, function() + return "partial", self[1][1].dimen + end) +end +function ConfirmBox:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1][1].dimen + end) end function ConfirmBox:onClose() diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua index 26c74b91c..2ff62936a 100644 --- a/frontend/ui/widget/dictquicklookup.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -265,6 +265,20 @@ function DictQuickLookup:update() end) end +function DictQuickLookup:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self.dict_frame.dimen + end) + return true +end + +function DictQuickLookup:onShow() + UIManager:setDirty(self, function() + return "partial", self.dict_frame.dimen + end) + return true +end + function DictQuickLookup:isPrevDictAvaiable() return self.dict_index > 1 end diff --git a/frontend/ui/widget/infomessage.lua b/frontend/ui/widget/infomessage.lua index fe17f4cf2..21e722a30 100644 --- a/frontend/ui/widget/infomessage.lua +++ b/frontend/ui/widget/infomessage.lua @@ -25,7 +25,6 @@ local InfoMessage = InputContainer:new{ face = Font:getFace("infofont", 25), text = "", timeout = nil, -- in seconds - closed = false, } function InfoMessage:init() @@ -79,30 +78,32 @@ function InfoMessage:init() } end -function InfoMessage:close() - if not self.closed then - self.closed = true - UIManager:close(self, "partial", self[1][1].dimen) - end +function InfoMessage:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1][1].dimen + end) + return true end function InfoMessage:onShow() -- triggered by the UIManager after we got successfully shown (not yet painted) + UIManager:setDirty(self, function() + return "partial", self[1][1].dimen + end) if self.timeout then - UIManager:scheduleIn(self.timeout, function() self:close() end) + UIManager:scheduleIn(self.timeout, function() UIManager:close(self) end) end - self.closed = false return true end function InfoMessage:onAnyKeyPressed() -- triggered by our defined key events - self:close() + UIManager:close(self) return true end function InfoMessage:onTapClose() - self:close() + UIManager:close(self) return true end diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua index a36d27470..a100773de 100644 --- a/frontend/ui/widget/inputdialog.lua +++ b/frontend/ui/widget/inputdialog.lua @@ -116,8 +116,18 @@ function InputDialog:init() }, self.dialog_frame, } - -- do a full refresh - is this really needed? - UIManager:setDirty("all", "full") +end + +function InputDialog:onShow() + UIManager:setDirty(self, function() + return "partial", self.dialog_frame.dimen + end) +end + +function InputDialog:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self.dialog_frame.dimen + end) end function InputDialog:onShowKeyboard() diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index fc342317f..1659a0453 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -87,6 +87,10 @@ function InputText:initTextBox(text) text_widget, } self.dimen = self[1]:getSize() + + UIManager:setDirty(self.parent, function() + return "partial", self[1].dimen + end) end function InputText:initCharlist(text) @@ -154,9 +158,6 @@ function InputText:addChar(char) table.insert(self.charlist, self.charpos, char) self.charpos = self.charpos + 1 self:initTextBox(table.concat(self.charlist)) - UIManager:setDirty(self.parent, function() - return "ui", self.dimen - end) end function InputText:delChar() @@ -164,13 +165,12 @@ function InputText:delChar() self.charpos = self.charpos - 1 table.remove(self.charlist, self.charpos) self:initTextBox(table.concat(self.charlist)) - UIManager:setDirty(self.parent, "ui") end function InputText:clear() self:initTextBox("") UIManager:setDirty(self.parent, function() - return "ui", self.dimen + return "ui", self[1][1].dimen end) end @@ -181,7 +181,7 @@ end function InputText:setText(text) self:initTextBox(text) UIManager:setDirty(self.parent, function() - return "partial", self.dimen + return "partial", self[1].dimen end) end diff --git a/frontend/ui/widget/linkbox.lua b/frontend/ui/widget/linkbox.lua index 29f72a0e3..2c7fa0364 100644 --- a/frontend/ui/widget/linkbox.lua +++ b/frontend/ui/widget/linkbox.lua @@ -33,7 +33,17 @@ function LinkBox:paintTo(bb) self.bordersize, self.color, self.radius) end +function LinkBox:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self.box + end) + return true +end + function LinkBox:onShow() + UIManager:setDirty(self, function() + return "partial", self.box + end) if self.timeout then UIManager:scheduleIn(self.timeout, function() UIManager:close(self) diff --git a/frontend/ui/widget/logindialog.lua b/frontend/ui/widget/logindialog.lua index 006a1f5f4..db1b84551 100644 --- a/frontend/ui/widget/logindialog.lua +++ b/frontend/ui/widget/logindialog.lua @@ -87,7 +87,6 @@ function LoginDialog:init() }, self.dialog_frame, } - UIManager:setDirty("all", "full") end function LoginDialog:getCredential() diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index b6f94cbd6..8f9e0bf0e 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -283,11 +283,13 @@ end function MenuItem:onTapSelect(arg, ges) local pos = self:getGesPosition(ges) self[1].invert = true - -- TODO: regional refresh - UIManager:setDirty(self.show_parent, "partial") + local refreshfunc = function() + return "partial", self[1].dimen + end + UIManager:setDirty(self.show_parent, refreshfunc) UIManager:scheduleIn(0.1, function() self[1].invert = false - UIManager:setDirty(self.show_parent, "partial") + UIManager:setDirty(self.show_parent, refreshfunc) self.menu:onMenuSelect(self.table, pos) end) return true @@ -296,11 +298,13 @@ end function MenuItem:onHoldSelect(arg, ges) local pos = self:getGesPosition(ges) self[1].invert = true - -- TODO: regional refresh - UIManager:setDirty(self.show_parent, "partial") + local refreshfunc = function() + return "partial", self[1].dimen + end + UIManager:setDirty(self.show_parent, refreshfunc) UIManager:scheduleIn(0.1, function() self[1].invert = false - UIManager:setDirty(self.show_parent, "partial") + UIManager:setDirty(self.show_parent, refreshfunc) self.menu:onMenuHold(self.table, pos) end) return true diff --git a/frontend/ui/widget/notification.lua b/frontend/ui/widget/notification.lua index 9bd2916b6..4d5051268 100644 --- a/frontend/ui/widget/notification.lua +++ b/frontend/ui/widget/notification.lua @@ -20,7 +20,6 @@ local Notification = InputContainer:new{ timeout = nil, margin = 5, padding = 5, - closed = false, } function Notification:init() @@ -56,25 +55,27 @@ function Notification:init() } end -function Notification:close() - if not self.closed then - self.closed = true - UIManager:close(self, "partial", self[1][1].dimen) - end +function Notification:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self[1][1].dimen + end) + return true end function Notification:onShow() -- triggered by the UIManager after we got successfully shown (not yet painted) + UIManager:setDirty(self, function() + return "partial", self[1][1].dimen + end) if self.timeout then - UIManager:scheduleIn(self.timeout, function() self:close() end) + UIManager:scheduleIn(self.timeout, function() UIManager:close(self) end) end - self.closed = false return true end function Notification:onAnyKeyPressed() -- triggered by our defined key events - self:close() + UIManager:close(self) return true end diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua index 1cc861c4c..55798e4fb 100644 --- a/frontend/ui/widget/virtualkeyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -102,21 +102,9 @@ function VirtualKey:update_keyboard() end) end -function VirtualKey:update_keyboard_inputbox() - local inputbox = self.keyboard.inputbox - UIManager:setDirty(self.keyboard, function() - DEBUG("update inputbox", inputbox.dimen) - return "ui", inputbox.dimen - end) - UIManager:setDirty(self.keyboard, function() - DEBUG("update keyboard", self[1].dimen) - return "ui", self[1].dimen - end) -end - function VirtualKey:onTapSelect() self[1].invert = true - self:update_keyboard_inputbox() + self:update_keyboard() if self.callback then self.callback() end @@ -126,7 +114,7 @@ end function VirtualKey:onHoldSelect() self[1].invert = true - self:update_keyboard_inputbox() + self:update_keyboard() if self.hold_callback then self.hold_callback() end @@ -227,6 +215,22 @@ function VirtualKeyboard:init() self:initLayout(self.layout) end +function VirtualKeyboard:_refresh() + UIManager:setDirty(self, function() + return "partial", self[1][1].dimen + end) +end + +function VirtualKeyboard:onShow() + self:_refresh() + return true +end + +function VirtualKeyboard:onCloseWidget() + self:_refresh() + return true +end + function VirtualKeyboard:initLayout(layout) local function VKLayout(b1, b2, b3, b4) local function boolnum(bool) @@ -319,13 +323,7 @@ function VirtualKeyboard:setLayout(key) if self.utf8mode then self.umlautmode = false end end self:initLayout() - UIManager:setDirty(self, function() - -- correct coordinates of keyboard - local dimen = self.dimen:copy() - dimen.y = Screen:getHeight() - dimen.h - DEBUG("update keyboard layout", dimen) - return "partial", dimen - end) + self:_refresh() end function VirtualKeyboard:addChar(key) From 844c1babf7d05c80b61c114c7f80ffb27eed259c Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Mon, 1 Dec 2014 15:09:00 +0000 Subject: [PATCH 3/4] UIManager:_refresh(): no more default refresh If no refresh type is specified, don't do a refresh. There should be now refresh types specified in all relevant places. --- frontend/ui/uimanager.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 7466d1cf3..6d79a6d17 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -350,8 +350,7 @@ region: Rect() that specifies the region to be updated Note that this should be the exception. --]] function UIManager:_refresh(mode, region) - -- default mode is partial - mode = mode or "partial" + if not mode then return end -- special case: full screen partial update -- will get promoted every self.FULL_REFRESH_COUNT updates if not region and mode == "partial" then From ff0fbbdb4bb6d1e9f04e4ade6963ce442bc0b102 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Mon, 1 Dec 2014 16:21:42 +0000 Subject: [PATCH 4/4] fix widget closing --- frontend/ui/widget/menu.lua | 4 ++++ frontend/ui/widget/touchmenu.lua | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index 8f9e0bf0e..26a093758 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -579,6 +579,10 @@ function Menu:init() end end +function Menu:onCloseWidget() + UIManager:setDirty(nil, "partial", self.dimen) +end + function Menu:updateItems(select_number) local old_dimen = self.dimen and self.dimen:copy() -- self.layout must be updated for focusmanager diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index 9ad556edd..ad766396e 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -384,6 +384,10 @@ function TouchMenu:init() self:updateItems() end +function TouchMenu:onCloseWidget() + UIManager:setDirty(nil, "partial", self.dimen) +end + function TouchMenu:_recalculateDimen() self.dimen.w = self.width