-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for hiding (skipping) non-linear EPUB fragments #6847
Conversation
local flow = self.ui.document:getPageFlow(page) | ||
page = self.ui.document:getPageNumberInFlow(page) | ||
if flow > 0 then | ||
page = T("[%1]%2", page, flow) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might need a translator's comment. Also screenshots would be nice. ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I confess I've used T(...)
without knowing what it means... I don't think this should be translated though, so I guess I should use ("[%1]%2"):format(page, flow)
, as in the footer code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you confused me by needlessly using the template function here when you're just doing string.format.
I don't think this should be translated though
You and I simply don't know (pinging @WaseemAlkurdi since I'm curious about Arabic), but even for a language like Dutch I might opt to localize it as ()
instead of []
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied that from the toc code, which is "translated", but the footer code is not (e.g. you cannot translate "%d / %d"
to "%d : %d"
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a bug then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Frenzie We would flip it normally for RTL, like a page number:
[2 / 14] 3
(page 2 out of 14 in non-linear flow number 3)
which would become:
3 [14 / 2]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the self-evident part. But you'd use those symbols? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Frenzie Ah. The circular brackets would be better, as you stated. Square brackets have no place in user-facing stuff (imagine them being used in a literary text, a novel of some sort?)
function ReaderToc:getChapterPagesLeft(pageno) | ||
--if self:isChapterEnd(pageno) then return 0 end | ||
local next_chapter = self:getNextChapter(pageno) | ||
if next_chapter then | ||
next_chapter = next_chapter - pageno - 1 | ||
local flow = self.ui.document:getPageFlow(pageno) | ||
-- Count pages until new chapter | ||
local pages_left = 0 | ||
local test_page = self.ui.document:getNextPage(pageno) | ||
while test_page > 0 do | ||
pages_left = pages_left + 1 | ||
if self:isChapterStart(test_page) then | ||
return pages_left | ||
end | ||
test_page = self.ui.document:getNextPage(test_page) | ||
end | ||
return next_chapter | ||
end | ||
|
||
function ReaderToc:getChapterPagesDone(pageno) | ||
if self:isChapterStart(pageno) then return 0 end | ||
local previous_chapter = self:getPreviousChapter(pageno) | ||
if previous_chapter then | ||
previous_chapter = pageno - previous_chapter | ||
local flow = self.ui.document:getPageFlow(pageno) | ||
-- Count pages until chapter start | ||
local pages_done = 0 | ||
local test_page = self.ui.document:getPrevPage(pageno) | ||
while test_page > 0 do | ||
pages_done = pages_done + 1 | ||
if self:isChapterStart(test_page) then | ||
return pages_done | ||
end | ||
test_page = self.ui.document:getPrevPage(test_page) | ||
end | ||
return previous_chapter | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there something wrong with the existing approach if !hasFlows
? If not, can we keep it in this case? ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing wrong, I just like it better to have a single solution than lots of if
s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getPreviousChapter
& co happen to be faster by using the ticks directly, though, instead of walking page-by-page ;)
for i,j in pairs(self.ui.toc:getTocTicksFlattened()) do | ||
if self.view.document:getPageFlow(j) == self.flow then | ||
self.progress_bar.ticks[i] = self.view.document:getPageNumberInFlow(j) | ||
else | ||
self.progress_bar.ticks[i] = nil | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same vein, only relevant if hasFlows
(well, has and show, I guess, actually) ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to iterate through getTocTicksFlattened()
via ipairs
. If it turns out the array is actually sparse, then we have a host of other buggy code that assumes it wouldn't be ;).
EDIT: But given the way it's built, it really never should be sparse, so that assumption should hold.
Mhhhh, first impression is not the best. I would have expected stuff to be a bit more like: if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
page = self.ui.pagemap:getXPointerPageLabel(page, true)
else if self.ui.hide_non_linear == true and document.hasNonLinearStuff() then
-- The new stuff I can skip when discovering the code.
your new code and new methods called only when necessary
else
-- the regular usually simpler stuff
page = self.ui.document:getPageFromXPointer(page)
end I'll get into your code :) and may be all that tight integration is needed (the diff is not that large) - but after 45mn reading the diff, I'm not yet passed this first impression :/ Letting my dev impressions on the side for now, my user impressions (haven't tried it, just from the screenshots and what I quickly got from the code):
|
Kinda agree ;p. Ideas:
|
That's the case. Everything (but the new menu item) should look the same as it does now when disabled.
Right, but that also happens now if I make some bookmarks with large font and others with small font.
Hmm... But I want to be able to enable it for all books by default, even if the current book does not have it. Also, I thought that this is something that affects the formatting of the book and the reading experience, and it's not a tool for navigation, so it seems to fit better the second menu, doesn't it? |
I think you need a way to show the user that this book has non-linear flows or not. No need for him to toggle it and then try to see if something has changed like total nb of pages to notice/guess that if not, there's no linear flow. So, the presence of this menu is a good indicator the document has them, and that there's a feature that may makes the reading experience better. Seeing that menu always and toggling it and seeing it has no effect won't advertize how nice that feature can be. As for the hold_callback to enable it on all books - well, you'll do that on a book that has it :) (in cre, you can't enable pdf stuff on all books).
It doesn't at all to me :) How it affects formatting is a side effect I'd say. Most of the things this PR changes are related to pages, TOC, Bookmarks, the skimto widget after all :) things that all are in that first menu. (For these 2 points, I consider your feature not much different than the Reference page stuff I added - So, it'd be nice they show up, work and are advertize quite similarly.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, better second impression after another hour reading :)
With better names and a bit more wrapping, it could be fine.
local flow = self.ui.document:getPageFlow(page) | ||
page = self.ui.document:getPageNumberInFlow(page) | ||
if flow > 0 then | ||
page = T("[%1]%2", page, flow) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happier if that kind of things would be written:
local page = self.ui.document:getPageFromXPointer(item.updated_highlight.pos0)
local flow = self.ui.document:getPageFlow(page) -- 0 when no (or not hidden) non-linear flows
if flow > 0 then
page = self.ui.document:getPageNumberInFlow(page)
page = T("[%1]%2", page, flow)
end
or even:
local page = self.ui.document:getPageFromXPointer(item.updated_highlight.pos0)
if self.ui.document:hasHiddenFlows() then
local flow = self.ui.document:getPageFlow(page) -- 0 when no (or not hidden) non-linear flows
if flow > 0 then
page = self.ui.document:getPageNumberInFlow(page)
page = T("[%1]%2", page, flow)
end
end
no matter the additional function call.
local left = footer.ui.toc:getChapterPagesLeft(footer.pageno) | ||
local left = footer.ui.toc:getChapterPagesLeft(footer.ui:getCurrentPage()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why that change for this one - and not for the others (like the one above you modified)?
Can footer.pageno be different from footer.ui:getCurrentPage() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can footer.pageno be different from footer.ui:getCurrentPage() ?
Yes, footer.pageno
is the page number shown in the footer, the "local" page in the current flow, while footer.ui:getCurrentPage()
is the global page number, counting all flows.
@@ -438,6 +448,7 @@ function ReaderFooter:init() | |||
return | |||
end | |||
|
|||
self.flow = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.current_flow
might be a more explicite name?
@@ -1869,20 +1887,38 @@ function ReaderFooter:_updateFooterText(force_repaint, force_recompute) | |||
end | |||
end | |||
|
|||
function ReaderFooter:onChangeViewMode() | |||
self:onPageUpdate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be a comment about why you need to call it.
(I have the feeling it would be called anyway because of other events, but better explicite than implicite if it being called multiple times is not an issue.)
@@ -55,7 +55,8 @@ local ReaderRolling = InputContainer:new{ | |||
-- With visible_pages=2, in 2-pages mode, ensure the first | |||
-- page is always odd or even (odd is logical to avoid a | |||
-- same page when turning first 2-pages set of document) | |||
odd_or_even_first_page = 1 -- 1 = odd, 2 = even, nil or others = free | |||
odd_or_even_first_page = 1, -- 1 = odd, 2 = even, nil or others = free | |||
hide_nonlinear = nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hide_nonlinear_flows
may be, to make it clearer it's related to "flows" elsewhere.
frontend/document/credocument.lua
Outdated
@@ -58,6 +58,10 @@ local CreDocument = Document:new{ | |||
default_css = "./data/cr3.css", | |||
provider = "crengine", | |||
provider_name = "Cool Reader Engine", | |||
|
|||
hide_nonlinear = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hide_nonlinear_flows
here too, to make it clearer it's related to "flows" elsewhere.
frontend/document/credocument.lua
Outdated
end | ||
end | ||
|
||
function CreDocument:hasFlows() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just seeing this one named hasHiddenFlows()
and checking for self.hide_nonlinear_flows
- and abused a bit more as wrappers - would make me quite happy with this PR.
(And moved above before all the other :*Flow*
functions.)
function CreDocument:cacheFlows() | ||
-- Build the cache tables "flows" and "page_in_flow", if there are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather see this one called and do its work only when hide_nonlinear_flows == true
@@ -90,8 +92,8 @@ function ProgressWidget:paintTo(bb, x, y) | |||
local bar_width = (my_size.w-2*self.margin_h) | |||
local y_pos = y + self.margin_v + self.bordersize | |||
local bar_height = my_size.h-2*(self.margin_v+self.bordersize) | |||
for i=1, #self.ticks do | |||
local tick_x = bar_width*(self.ticks[i]/self.last) | |||
for i,tick in pairs(self.ticks) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to not switch from array iterator to pairs()
. We had bad experiences with pairs()
in these kind of situations, and switch a lot to ipairs
or for i=1, #something
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That one is still outstanding ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And since we were talking about rounding, I realize that tick_x
was already never rounded here, wheee... -_-".
(At a quick glance, bar_width
should always be an int, but the MUL against tick/last
might change that.
@@ -26,6 +26,7 @@ local order = { | |||
typeset = { | |||
"set_render_style", | |||
"style_tweaks", | |||
"hide_nonlinear", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hide_nonlinear_flows
too to make that more explicite.
Following up on #6847 (comment) above here (as I don't like this discussion hidden in the hidden comments above).
That's mostly how KOReader works everywhere. Roundabouts is its middle name (think about all the events). So, it's not at all an issue for me.
Well, up until you introduced a cache for page flows in it, it was just a thin wrapper, a pure proxy to crengine, with not much state inside of it. And I think until some bigger refactoring is needed, it should stay that way. There is one little issue with handleEngineCallback: it's done in some kind of out of the main Lua state, and it won't crash the app if you have some coding error in it - so, we don't want to do too much stuff thru it: koreader/frontend/apps/reader/modules/readerrolling.lua Lines 236 to 240 in 5ed2400
I see you do Not for you to do in this PR (unless you think that could make your handling clearer) but a more generic solution to handling that could be: (I'd say that even if your cached page flows are internal to CreDocument, updating them should be done from ReaderRolling, in the upper equivalent that calls the lower
No real contract on that I think. But the implementation ( |
end, | ||
chapter_time_to_read = function(footer) | ||
local symbol_type = footer.settings.item_prefix or "icons" | ||
local prefix = symbol_prefix[symbol_type].chapter_time_to_read | ||
local left = footer.ui.toc:getChapterPagesLeft(footer.pageno) | ||
local left = footer.ui.toc:getChapterPagesLeft(footer.ui:getCurrentPage()) | ||
return footer:getDataFromStatistics( | ||
prefix .. " ", (left and left or footer.pages - footer.pageno)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not affected by this PR, but is this construction needed? Wouldn't (left or footer.pages - footer.pageno)
be exactly the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks to me that indeed, it's exactly the same (unless I miss something with Lua pecularities :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT, If there are no ticks at all (i.e., no chapter breaks), ReaderToc:getNextChapter
will return nil
, and ReaderToc:getChapterPagesLeft
will return it as-is.
Maths with a nil in the mix == kablooey ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That explains the need for left or ...
, but not for left and left
? If left
is nil
, left or "foo"
is "foo"
, and left and left or "foo"
is "foo"
as well... at least as far as I can see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yeah, I totally skipped over the fact that there was an or
after :D.
Maybe a matter for a different PR, but would it make sense to set the default bookmark title not to the page number, but to some placeholder, like |
Yep, that would make sense. And for a different PR. #5794 has some discussion about better handling of all that bookmark mess. (Fell free to take over that task if you are courageous :) |
for i=1, #self.ticks do | ||
local tick_x = bar_width*(self.ticks[i]/self.last) | ||
for i,tick in pairs(self.ticks) do | ||
local tick_x = bar_width*((tick-0.5)/self.last) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm... not necessarily a fan of that ;).
And, at the very least, it'll probably require rounding to ensure it doesn't randomly decide to jump a pixel or not ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, either there is a non-existing "page 0" represented in the progress bar, or the last page is missing. If I use the plain page numbers for the non-linear filling, I get an overflow:
which I can solve by using page-1
, but then the ticks are off:
So with tick-0.5
the ticks are "midpage", they're still off, but at least they're not at the boundary of any page:
As for rounding, I don't think it's needed. tick
should be an integer, and even though tick_x
can jump one pixel, it will always be between the values corresponding to tick
and tick-1
. In the case when each page takes less than one pixel, I don't really care which one it is, there's not enough resolution anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather keep the current behavior and just fix the overflow, FWIW ;).
(As in, they're meant to be at boundaries: they are the boundaries).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To fix the overflow and keep the ticks at the boundary, everything should be moved -1
page. Then the first page would have no filled progress bar, and the last page would not be 100% filled (which would make sense if the bar means "pages already read"), or the progress bar should be divided in pages-1
chunks, instead of pages
.
But ok, I'll leave it as is. I don't really use the skim widget enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for rounding, I don't think it's needed
Not rounding what might be passed to the drawing code has been the cause of positionning & fitting issues (even in upper containers far from what you're dealing with) in the past. So, please do if you can :)
I have no real opinion on #6831 because I don't use it that much to jump - I just expect it to be "clean", so my preference among the 3 above screenshots is the first (without the overflow of course :) The 2 others, no matter how correct they may be for the person who gave it some thoughts, will look like a bug for most of the other users :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first is wronger, because the first page is non-linear, and it appears as the second, it's the same -1 offset. If the first page is non-linear, it should go from 0 to 1, and if the last 2 pages (out of 100) are non-linear, the grey should go from 98 to 100 (even though the pages are 99 and 100).
So, my point is the grey blocks in the 2nd and 3rd example are correct. The ticks in 1st and 2nd are correct, if they are interpreted as marking the end of a page where a chapter starts, and the filled bar is correct if it's interpreted as all pages up to (and including) the current one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My stance on the whole #6831 discussion was that I might be agreeable to modifying the way the bar is filled in, but that the ticks should very much stick to what they're currently doing.
And as the two are somewhat intricately linked, that only leaves room to really fudge the start & end of the bar, and possibly how the current page is filled in (or not) ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To fix the overflow and keep the ticks at the boundary, everything should be moved
-1
page. Then the first page would have no filled progress bar, and the last page would not be 100% filled (which would make sense if the bar means "pages already read"), or the progress bar should be divided inpages-1
chunks, instead ofpages
.
FWIW, I'd probably be amenable to either of those approaches, I think ;).
(Never seeing the bar fully filled on the last page kinda makes sense to me).
I think I've addressed most, if not all the comments so far with the new commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine (readable, and feeling safe with the hasHiddenFlows() wrappers :)
Mostly nitpicks:
if self.ui.document:getPagenNumberInFlow(i) == number and | ||
self.ui.document:getPageFlow(i) == flow then | ||
self.ui:handleEvent(Event:new("GotoPage", i)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Indent a bit more line 154, or make it all on line 153. That too small indentation difference makes me read it wrong the first time - and wondered about the following.)
Can't you break before you reach i=getPageCount() if the number in flow provided is > getPagenNumberInFlow() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean if I want to go to page 30 in a flow that has only 5 pages? Sure... also if I want to go to page 0 or -7.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's what I mean (but mostly to not just go scan 2900 pages in a 3000 pages books to realize an early flow won't be found in there :)
self:resetToc() | ||
self.ui:handleEvent(Event:new("TocUpdated")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resetToc() just clears the TOC data (so it's rebuild later when needed).
Don't you need it updated for when you catch TocUpdated (or so that that "TocUpdated" event is true to its name) ?
(But beware, rebuilding the TOC might be expensive, so that's why we delay it until needed.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... Maybe I should just change the name, because as I see it, when the TOC is reset, the footer needs to rebuild it to get the markers. So yes, I need the updated TOC, but I guess this need triggers the rebuild.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please have a quick check that on loading a book (with cache or without), the TOC is only built once.
(I remember #3292 and #3261 (comment) - which are quite old - dunno if these thoughts are still relevant :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I think there was one TOC too many which should be fixed now.
frontend/document/credocument.lua
Outdated
for test_page=page+1, self:getPageCount() do | ||
local test_page_flow = self:getPageFlow(test_page) | ||
if test_page_flow == flow or test_page_flow == 0 then | ||
return test_page | ||
end | ||
end | ||
return 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No case for breaking that for
loop before reaching getPageCount() ? (I guess you can't for flow 0, but just asking).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. You have to keep testing until you find flow 0 or the end of the document. Unless you know in advance that a) you have reached the end of the current flow (this we can know as soon as a different flow is found), and b) there are no remaining pages in flow 0 (this is the tricky part).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But nothing that another cache item cannot fix.
@@ -117,7 +118,7 @@ function ProgressWidget:paintTo(bb, x, y) | |||
local bar_width = (my_size.w-2*self.margin_h) | |||
local y_pos = y + self.margin_v + self.bordersize | |||
local bar_height = my_size.h-2*(self.margin_v+self.bordersize) | |||
for i,tick in pairs(self.ticks) do | |||
for i,tick in ipairs(self.ticks) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We like a space after a comma, like in English :)
function ReaderFooter:onTocReset() | ||
self:setTocMarkers(true) | ||
self:onUpdateFooter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how soon after a toc reset the TOC was filled again before this PR (might be that it was delayed after a repaint, dunno). But with this, is will be immediately filled.
(I can't answer that question after a quick look at the code, so, just asking in case someone get an idea :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that ReaderRolling:updatePos()
had before:
self.ui:handleEvent(Event:new("UpdateToc"))
self.view.footer:setTocMarkers(true)
self.view.footer:onUpdateFooter()
so nothing should have changed in that particular chain of events.
@@ -457,6 +468,31 @@ You can set how many lines are shown.]]) | |||
help_text = _([[When page overlap is enabled, some lines from the previous pages are shown on the next page.]]), | |||
sub_item_table = page_overlap_menu, | |||
} | |||
if self.view.document:hasNonLinearFlows() then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we use self.view.document
in a few modules - but not in this one, readerrolling.
The canonical way to access the document object is usually with self.ui.document
(ui
instead of view
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least readerfooter uses both self.ui.document
and self.view.document
. Any reason for this or is it OK if I change them all to self.ui.document
too?
frontend/document/credocument.lua
Outdated
if test_page_flow ~= flow and test_page > last_linear_page then | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you have/use a getLastPageInFlow(flow) when flow > 0 (like you have in the next function) ?
As when a flow is done, you can't meet it again - so it's no use checking up to the last linear page. No?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't meet it again, but you will meet flow 0 eventually (unless test_page > last_linear_page
), and that will be the "next page". I could limit the loop to math.max(self:getLastPageInFlow(flow), self:getLastLinearPage())
.
ETA: I think I misunderstood you and forgot there is no getLastPageInFlow
currently...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I misunderstood this function :)
-- Get the next/prev page number, skipping non-linear flows,
I thought you could use it to navigate pages inside a non-linear flow - and that if you're in flow No7 out of 19, you don't need to test pages until the end of the document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You skip non-linear flows, but linear pages may be interspersed between them, and we want to stop there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you really don't use CreDocument:getNextPage(p) to page forward inside non-linear flows (and expecting to get the next page inside this same non-linear flow)?
OK, I guess you do (so, this comment is lying :) and you'll stop looping when you meet back a page from flow 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There could be another performance improvement: when a different non-linear flow is found, instead of trying pages one by one, I could in principle skip all n pages in the flow in one go. But I somehow liked the simplicity of just paging through, it makes fewer assumptions about how the flows behave (for instance, non-linear flows should not be interleaved, but the one-by-one method would work even if that was the case).
frontend/document/credocument.lua
Outdated
elseif page == 0 then | ||
return self.getLastLinearPage() | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In onGoToBegenning, you provide page=0 to go to the first page - which sounds like it's not what you do :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, I got them mixed.
Maybe I should use #6859 instead of forcing |
Isn't a reset already forced when you call But may be you could have some of them not be |
I had #6809 (comment) in mind, but I'll try reproducing/investigating it again, and I'll come back if I can't figure it out. |
Had a try on my Kobo, looks ok (as far as the things I care about as concerned, not tested bookmarks, some footer items...) So, I reported previously that 90% of my books don't have any non-linear stuff. I think the footer marking is good ( |
Still a few luacheck warnings to solve. |
Now some issues with unit tests that might need some update to the new functions.
|
Add option to hide (skip) non-linear fragments, only working in 1-page mode. Tweaks mostly to footer, toc and skim code to make it clear(er) which pages belong to linear or non-linear fragments.
As an aside, it should be "ToC," not "Toc." ;-) Cf. <koreader#6847>.
As an aside, it should be "ToC," not "Toc." ;-) Cf. <#6847>. * Also fix newlines in to be translated string
@Jellby : hope you haven't forgotten everything about this PR :) I'm reusing much of it to implement "handmade hidden flows" (#10193 (comment)), that would allow one to set hidden flows on PDF documents (and also on CRE documents whether they have non-linear fragments or not). I have a few questions regarding your code: koreader/frontend/document/document.lua Lines 235 to 244 in 38d468f
(I have to make ReaderPaging use these instead of You allow these methods to return Also, when called with Also, in the snippet above, it looks like there's a logical bug ( - return (new_page > 0 and new_page < self.info.number_of_pages) and new_page or 0
+ return (new_page > 0 and new_page <= self.info.number_of_pages) and new_page or 0 Also mentionning a little bug (that is not part of my scope :) that I noticed, and that I can reproduce on an EPUB with (sick) non-linear fragments: With chapters spanning fragment boundaries like above, the footer "page left in chapter" would show in the above case at the position of the arrow: |
I guess so, or just to return a reproducible and recognizable value whenever something wrong happens.
I think that was simply to have kind of "overloaded" functions that still do something useful with
You're probably right.
I believe I consciously assumed that fragments and chapters would be "properly nested", either a fragment contains full chapters or is fully contained in a chapter. I knew that's not necessarily the case, but it certainly matches my use cases, and figured it would also be the most common situation. Given that there is formally no concept of "chapter" in epub 2 (only TOC and hyperlink targets, which may signal the "beginning", but no the end of a chapter), I wouldn't consider the current behaviour wrong, just... "creative" :) |
No, you're right, it works - as undocumented ;). I missed your comment explaining the implicit behaviour :) (Was expecting some kind of symetry.)
Got it. But when I read them first, it feels very twisted that |
This is the frontend implementation of #6809, to be merged after koreader/koreader-base#1228 (see koreader/crengine#391 too)
The core of the implementation is pretty basic: just create
Document:getPrevPage
andDocument:getNextPage
, which return the prev/next page number. By default they arepage-1
andpage+1
, but if a document contains non-linear flows, they can be skipped. If already inside a non-linear flow, paging works normally, until the boundary is reached, where it continues on the main (linear) flow, skipping other non-linear flows that may be in-between. The non-linear pages are still accessible through links, goto, skim, bookmarks... it's only page back/forward that are affected (if enabled).Some conventions (that can be discussed and changed):
x // y
(double slash), andx
andy
refer only to the linear pages (non-linear pages are not counted here). The intent is to succinctly indicate that there are uncounted pages.[x / y]z
, wherex
andy
refer only to this particular non-linear flow, andz
is the number of the flow.[x]y
wherex
is the "local" page number and "y" is the number of the flow.[x]y
format is supported, in which casey=0
corresponds to the linear flow.Setting help
Footer, linear
Footer, non-linear
Go to window
Skim window
Bookmarks
Closes #6809
This change is