InfoMessage: allows being drawn only after a delay

- InfoMessage: add an option show_delay.
- MovableContainer: avoid possible crash when
  not yet painted.
- ReaderDictionary: use show_delay=0.5 instead of
  scheduleIn(0.5n...) (a5b133da) as we need the
  InfoWidget to be known to UIManager to catch tap
  and allow interrupting lookups properly.
- ReaderDictionary: rework handling of no_refresh_on_close
  (6162c287) with proper regions comparisons
pull/7095/head
poire-z 3 years ago
parent dd74194e0a
commit cac7db1a1c

@ -646,17 +646,18 @@ function ReaderDictionary:cleanSelection(text)
return text
end
function ReaderDictionary:showLookupInfo(word)
function ReaderDictionary:showLookupInfo(word, show_delay)
local text = T(self.lookup_msg, word)
self.lookup_progress_msg = InfoMessage:new{text=text, no_refresh_on_close=true}
self.lookup_progress_msg = InfoMessage:new{
text = text,
show_delay = show_delay,
}
UIManager:show(self.lookup_progress_msg)
-- UIManager:forceRePaint()
end
function ReaderDictionary:dismissLookupInfo()
if self.lookup_progress_msg then
UIManager:close(self.lookup_progress_msg)
-- UIManager:forceRePaint()
end
self.lookup_progress_msg = nil
end
@ -819,12 +820,9 @@ function ReaderDictionary:stardictLookup(word, dict_names, fuzzy_search, box, li
return
end
if fuzzy_search then
UIManager:scheduleIn(0.5, self.showLookupInfo, self, word)
end
self:showLookupInfo(word, 0.5)
local results = self:startSdcv(word, dict_names, fuzzy_search)
UIManager:unschedule(self.showLookupInfo)
self:showDict(word, tidyMarkup(results), box, link)
end
@ -857,17 +855,22 @@ function ReaderDictionary:showDict(word, results, box, link)
self:onHtmlDictionaryLinkTapped(dictionary, html_link)
end,
}
table.insert(self.dict_window_list, self.dict_window)
UIManager:show(self.dict_window)
if self.lookup_progress_msg then
-- If we have a lookup InfoMessage, and it's taller than us, make it refresh on close
if self.lookup_progress_msg[1][1] and self.lookup_progress_msg[1][1].dimen and self.lookup_progress_msg[1][1].dimen.h >= self.dict_window.height then
self.lookup_progress_msg.no_refresh_on_close = nil
-- If we have a lookup InfoMessage that ended up being displayed, make
-- it *not* refresh on close if it is hidden by our DictQuickLookup
-- to avoid refreshes competition and possible glitches
local msg_dimen = self.lookup_progress_msg:getVisibleArea()
if msg_dimen then -- not invisible
local dict_dimen = self.dict_window:getInitialVisibleArea()
if dict_dimen and dict_dimen:contains(msg_dimen) then
self.lookup_progress_msg.no_refresh_on_close = true
end
end
end
table.insert(self.dict_window_list, self.dict_window)
UIManager:show(self.dict_window)
end
-- Delay the dismiss, so we can flip the no_refresh_on_close flag if the InfoMessage is taller than the DictQuickLookup...
self:dismissLookupInfo()
if results and results[1] then
UIManager:show(self.dict_window)

@ -189,6 +189,9 @@ end
function MovableContainer:onMovableSwipe(_, ges)
logger.dbg("MovableContainer:onMovableSwipe", ges)
if not self.dimen then -- not yet painted
return false
end
if not ges.pos:intersectWith(self.dimen) then
-- with swipe, ges.pos is swipe's start position, which should
-- be on us to consider it
@ -216,6 +219,9 @@ function MovableContainer:onMovableTouch(_, ges)
-- First "pan" event may already be outsise us, we need to
-- remember any "touch" event on us prior to "pan"
logger.dbg("MovableContainer:onMovableTouch", ges)
if not self.dimen then -- not yet painted
return false
end
if ges.pos:intersectWith(self.dimen) then
self._touch_pre_pan_was_inside = true
self._move_relative_x = ges.pos.x
@ -228,6 +234,9 @@ end
function MovableContainer:onMovableHold(_, ges)
logger.dbg("MovableContainer:onMovableHold", ges)
if not self.dimen then -- not yet painted
return false
end
if ges.pos:intersectWith(self.dimen) then
self._moving = true -- start of pan
self._move_relative_x = ges.pos.x
@ -239,6 +248,9 @@ end
function MovableContainer:onMovableHoldPan(_, ges)
logger.dbg("MovableContainer:onMovableHoldPan", ges)
if not self.dimen then -- not yet painted
return false
end
-- we may sometimes not see the "hold" event
if ges.pos:intersectWith(self.dimen) or self._moving or self._touch_pre_pan_was_inside then
self._touch_pre_pan_was_inside = false -- reset it
@ -250,6 +262,9 @@ end
function MovableContainer:onMovableHoldRelease(_, ges)
logger.dbg("MovableContainer:onMovableHoldRelease", ges)
if not self.dimen then -- not yet painted
return false
end
if self._moving or self._touch_pre_pan_was_inside then
self._moving = false
if not self._move_relative_x or not self._move_relative_y then
@ -273,6 +288,9 @@ end
function MovableContainer:onMovablePan(_, ges)
logger.dbg("MovableContainer:onMovablePan", ges)
if not self.dimen then -- not yet painted
return false
end
if ges.pos:intersectWith(self.dimen) or self._moving or self._touch_pre_pan_was_inside then
self._touch_pre_pan_was_inside = false -- reset it
self._moving = true
@ -285,6 +303,9 @@ end
function MovableContainer:onMovablePanRelease(_, ges)
logger.dbg("MovableContainer:onMovablePanRelease", ges)
if not self.dimen then -- not yet painted
return false
end
if self._moving then
self:_moveBy(self._move_relative_x, self._move_relative_y)
self._moving = false

@ -607,6 +607,26 @@ function DictQuickLookup:update()
end)
end
function DictQuickLookup:getInitialVisibleArea()
-- Some positionning happens only at paintTo() time, but we want
-- to know this before. So, do a bit like WidgetContainer does
-- (without any MovableContainer offset)
local dict_size = self.dict_frame:getSize()
local area = Geom:new{
w = dict_size.w,
h = dict_size.h,
x = self.region.x + math.floor((self.region.w - dict_size.w)/2)
}
if self.align == "top" then
area.y = self.region.y
elseif self.align == "bottom" then
area.y = self.region.y + self.region.h - dict_size.h
elseif self.align == "center" then
area.x = self.region.y + math.floor((self.region.h - dict_size.h)/2)
end
return area
end
function DictQuickLookup:onCloseWidget()
-- Free our widget and subwidgets' resources (especially
-- definitions' TextBoxWidget bb, HtmlBoxWidget bb and MuPDF instance,

@ -67,6 +67,8 @@ local InfoMessage = InputContainer:new{
auto_para_direction = nil,
-- Don't call setDirty when closing the widget
no_refresh_on_close = nil,
-- Only have it painted after this delay (dismissing still works before it's shown)
show_delay = nil,
}
function InfoMessage:init()
@ -184,9 +186,18 @@ function InfoMessage:init()
end
end
end
if self.show_delay then
-- Don't have UIManager setDirty us yet
self.invisible = true
end
end
function InfoMessage:onCloseWidget()
if self.invisible then
-- Still invisible, no setDirty needed
return true
end
if self.no_refresh_on_close then
return true
end
@ -198,28 +209,58 @@ function InfoMessage:onCloseWidget()
end
function InfoMessage:onShow()
-- triggered by the UIManager after we got successfully shown (not yet painted)
-- triggered by the UIManager after we got successfully show()'n (not yet painted)
if self.show_delay and self.invisible then
-- Let us be shown after this delay
self._delayed_show_action = function()
self._delayed_show_action = nil
self.invisible = false
self:onShow()
end
UIManager:scheduleIn(self.show_delay, self._delayed_show_action)
return true
end
-- set our region to be dirty, so UImanager will call our paintTo()
UIManager:setDirty(self, function()
return "ui", self[1][1].dimen
end)
-- schedule us to close ourself if timeout provided
if self.timeout then
UIManager:scheduleIn(self.timeout, function() UIManager:close(self) end)
end
return true
end
function InfoMessage:onAnyKeyPressed()
-- triggered by our defined key events
function InfoMessage:getVisibleArea()
if not self.invisible then
return self[1][1].dimen
end
end
function InfoMessage:paintTo(bb, x, y)
if self.invisible then
return
end
InputContainer.paintTo(self, bb, x, y)
end
function InfoMessage:dismiss()
if self._delayed_show_action then
UIManager:unschedule(self._delayed_show_action)
end
self.dismiss_callback()
UIManager:close(self)
end
function InfoMessage:onAnyKeyPressed()
self:dismiss()
if self.readonly ~= true then
return true
end
end
function InfoMessage:onTapClose()
self.dismiss_callback()
UIManager:close(self)
self:dismiss()
if self.readonly ~= true then
return true
end

Loading…
Cancel
Save