mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
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
This commit is contained in:
@@ -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,
|
||||
}
|
||||
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
|
||||
end
|
||||
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 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
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user