-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
simplify iterating with Cursor #1279
Conversation
c2e6fb9
to
76dce83
Compare
// reset iterator | ||
//--------------------------------------------------------- | ||
|
||
void Cursor::iterate(bool type) |
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 would change "type" to "selection" or "throughSelection"
I believe it's going in the right selection. |
1/ I don't really know #1271. It seems not yet finished. So, I'd propose: Remove the iterator stuff from Cursor and create a new class Iterator which will do the whole job (including walking through segments) in one loop. It can make sure it's not going to interfere with #1271, because it can initialize a local cursor to not count for repeats, and we can decide later if we want to integrate it. So we'd get something like:
One could also provide a second constructor newIterator(overSelection, elementFilter). The filter could be set to Element.CHORD, for example if we're not interested in anything else.
There needs to be a way to set a cursor to the same position of the Iterator to be able to work on other tracks at the same position. I can think of two ways doing this:
The second version has the disadvantage of creating a new object every time it's called. Thinking of it: We could also add an Iterator type that would not go through the score track by track but segment by segment (the type needed for courtesy accidentals). This could be done in the same class. We'd just need a different constructor: Score.newSegmentIterator(elementFilter) or something like that? Won't be able to do this today anyway. So, I'll wait for your comments. |
I don't understand the difference between a Cursor and an Iterator in your example. Also I don't get how it would simplify things to have two classes to go through a score. What if a Cursor would be defined like this
// possibly we can add previousXXX methods too |
My commit #1271 is done. It simply expose the measure number and allows the cursor to iterate on expanded repeats. |
I thought it would be a nice to have two different classes for different ways of accessing the score. Cursor for random access, and Iterator for an ordered list like access. But maybe we don't need that. I have some questions concerning your (Lasconic's) definition: Concerning 'expandrepeat': What should a Cursor do, when called with onSelection == true and expandrepeat == true, if the selection starts in the middle of a repeated section? Once it hits the repeat bar line, it cannot go back to the beginning of the repeated section, because that is not part of the selection, repeating only the selected part doesn't make much sense either. So would we just skip that repeat? |
First, let me state I'm glad to have this discussion with someone and I hope we will manage to make something simple and usable. If we can manage to have both random access and iteration in the same class, I believe it's better. If the class becomes too complicated then ok, let's go for two classes. I would see Cursor.next(type) as a shortcut and Cursor.nextTrack() as a finer iteration to allow segment first or track first iteration. Cursor.next() would be hardwired to do segment first if we take your first example. #1279 (comment). If we go for two classes, it's also valid for the Iterator. Should we have hasSelection in score? |
Yes, let's see that we come up with a powerful yet simple to use Cursor. :-) Constructors:
next group ('type' always optional):
This extra nextTrack() would be needed for iterating parts. (Actually my courtesy accidental plugin would only be able to use nextTrack if this was provided):
keep:
editing group:
I think we should also discuss this last group. But maybe not here. |
I don't get Cursor::nextTrack(type,startTrack,endTrack) Since we are at it, I would revise Cursor::rewind() and remove the param. Rewind would rewind to the start of the cursor as defined by the newCursor "constructor". And maybe toEnd() or similar to go to the end of the selection/score. Also, could be good to know if the cursor is operating on the full score or not once initialized. Same for expandRepeat. But I would make them read only. So no way to switch from expandRepeat to not expand repeat with the same cursor. |
About Cursor::nextTrack(type,startTrack,endTrack)
On the other hand:
Well, I like the second version better. Changes to the definition of Cursor:
|
One more thought about Cursor::toEnd() |
About cursor.nextTrack(Element.CHORD,startTrack,endTrack) |
I'd need a part cursor. For a flute that would be a staff, but for a piano it would be two staves.
Of course we could also provide a staff cursor with little more effort.
|
Yes. I don't have strong opinion on adding newStaff/PartCursor or providing nextXXX variants with start/end tracks. |
I think I'd vote for nextTrack(type,start,end), because it's more flexible and easier to implement. And I don't think we'd need it for the other next functions.
This would do the trick for next(). |
I think I was just complicating things here... Old comment:
Or allow the argument elementType to be an array. This wouldn't kill my nextTrack(type,start,end) idea. |
Needs a rework to be applied for current master |
This adds to Cursor:
property 'inSelection' is true if the current cursor position is inside the selection
property 'hasSelection' is true if there is a selection
will iterate over all segments of current track in the selection
function 'iterate(type)' resets the cursor to start of score (type==false) or selection (type==true)
function 'iterating()' remains true while there are still tracks/staves to be iterated
functions 'nextTrack()' and 'nextStaff()' setting the iterator to the beginning of the next track or staff. (according to type set when calling iterate).
will iterate over the selection track by track.
Below is a sample that iterates over all notes and grace notes of the selection or - if none - the whole score: