#17 split segments in instrument track (first draft)

thorsten mueller

this is the first draft for the split functionality in the instrument track. the song editor has two new buttons (sorry, no images yet): Split and Merge (merge coming next)

to split a segment simply choose Split Mode and move the mouse over the segment. it will show a blue marker between two bars if it can split at this position. if the marker is red, this means that a note is overlapping from a previous bar and split can’t be done here.
click the mouse at a blue position and the segment will be split in two.

notes about the code (by file):

declares two virtual methods isSplitMode() and isMergeMode() which by default return false. subclasses must overwrite those to allow splitting

songe_ditor.h & song_editor.cpp
has now the two new buttons and overwrites isSplitMode() and isMergeMode() to return their state.

pattern.h & pattern.cpp
the pattern class has a new function:
virtual bool hasNotePlayingAt( const midiTime & _t ) const;
which returns true if at the position a note is playing
further it declares a signal patternUpdate() which is emitted after the split (see later about details)

the patternView class has the most changes, since it handles all the gui stuff for showing the split markers and the method that does the actual copying.
mainly it adds enterEvent and leaveEvent and adds functionality to mouseMoveEvent(), paintEvent() and mousePressEvent()

all my changes are marked with
// rymr
i will remove this in the final version, for now it helps to find the new parts in the code.

- undo/redo function.
this could be tricky. i must read into the existing undo code first. i will most likely wait with implementing it, until i finished merging of segments, since that’s what undo a split would be.

- handling time signature different from 4/4
the system seems to be broken somehow (at least in dev branch). changing the time sig has strange effects, eg. it doesn’t calculate the number of bars properly. in some time sig settings notes are not aligned to the grid. maybe if this works in general, my function will work too.

- piano roll
for now i implemented a signal ‘patternUpdate()’ which is emitted when a split is made. piano roll is connected to this signal and will call setCurrentPattern() when it is received.
the pattern class already has a signal dataChanged(). but this is emitted whenever any change is made, including changes made in piano roll itself. using this would double the repaints for no reason (and there are already quite a lot of repaints in piano roll).
a possible solution would be to remove all updates from piano roll related to note edits and let it fully rely on receiving dataChange() signals from the pattern, which would make this a cleaner solution.
In general the painting in piano roll could need some work. simply moving the mouse over it creates an tremendous amount of paints.

i will work over details of the code. but i would like to get some input on the code and the user interface as soon as possible, so i can adjust things if you want a different implementation


  • First of all: thanks for your work!

    As discussed on the mailinglist, the old concept of "modes" is deprecated and shouldn't be followed anymore. Instead please create buttons which act once, i.e. when you click the split-button, the cursor shape is changed and allows to click one segment which will be splitted then. Reverse procedure for merge: after various segments were selected, you can click the merge button and the segments will get merged. All other behaviour is undesired.

    • assigned_to: nobody --> tobydox