S splits a pattern at mouse cursor
This commit is contained in:
parent
c3cf05372d
commit
7f7ebbc862
|
@ -118,6 +118,7 @@ Shift+Click+Drag: Move copy of pattern(s) at cursor.
|
|||
+Click+Drag: Move pattern link(s) at cursor.
|
||||
Delete: Remove selected patterns.
|
||||
Ctrl+J: Join patterns across tracks into one.
|
||||
S: Split patterns at cursor.
|
||||
Ctrl+D: Duplicate selection.
|
||||
Ctrl+Shift+D: Duplicate selection as link.
|
||||
Shift+Left/Right: Move patterns along track (+-step).
|
||||
|
|
22
model.cpp
22
model.cpp
|
@ -262,6 +262,28 @@ void Pattern::copy_from(const Pattern &pattern) {
|
|||
}
|
||||
}
|
||||
|
||||
void Pattern::move_frames(int row, int step, int channel) {
|
||||
int length = get_length();
|
||||
|
||||
Pattern::iterator iter;
|
||||
for (Pattern::iterator iter = begin();
|
||||
iter != end(); ++iter) {
|
||||
int frame = iter->second.frame;
|
||||
if (frame < row)
|
||||
continue;
|
||||
if ((channel >= 0) && (iter->second.channel != channel))
|
||||
continue;
|
||||
int newframe = frame + step;
|
||||
if ((newframe < row) || (newframe >= length)) {
|
||||
iter->second.frame = -1; // will be deleted
|
||||
} else {
|
||||
iter->second.frame = newframe;
|
||||
}
|
||||
}
|
||||
|
||||
update_keys();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
SongEvent::SongEvent() {
|
||||
|
|
|
@ -160,6 +160,8 @@ public:
|
|||
void update_keys();
|
||||
void copy_from(const Pattern &pattern);
|
||||
|
||||
void move_frames(int row, int step, int channel);
|
||||
|
||||
Pattern();
|
||||
protected:
|
||||
// length in frames
|
||||
|
|
|
@ -1212,25 +1212,9 @@ void PatternView::transpose(int step) {
|
|||
void PatternView::move_frames(int step, bool all_channels/*=false*/) {
|
||||
int row = cursor.get_row();
|
||||
int channel = cursor.get_channel();
|
||||
int length = get_pattern()->get_length();
|
||||
|
||||
Pattern::iterator iter;
|
||||
for (Pattern::iterator iter = get_pattern()->begin();
|
||||
iter != get_pattern()->end(); ++iter) {
|
||||
int frame = iter->second.frame;
|
||||
if (frame < row)
|
||||
continue;
|
||||
if (!all_channels && (iter->second.channel != channel))
|
||||
continue;
|
||||
int newframe = frame + step;
|
||||
if ((newframe < row) || (newframe >= length)) {
|
||||
iter->second.frame = -1; // will be deleted
|
||||
} else {
|
||||
iter->second.frame = newframe;
|
||||
}
|
||||
}
|
||||
get_pattern()->move_frames(row, step, (all_channels?-1:channel));
|
||||
|
||||
get_pattern()->update_keys();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
|
39
songview.cpp
39
songview.cpp
|
@ -907,6 +907,44 @@ void SongView::set_loop_end() {
|
|||
invalidate_loop();
|
||||
}
|
||||
|
||||
void SongView::split_at_mouse_cursor() {
|
||||
SongCursor cur(*this);
|
||||
cur.set_pos(cursor_x, cursor_y);
|
||||
|
||||
int frame = quantize_frame(cur.get_frame());
|
||||
|
||||
invalidate_selection();
|
||||
Song::IterList new_selection;
|
||||
|
||||
Song::IterList::iterator iter;
|
||||
for (iter = selection.begin(); iter != selection.end(); ++iter) {
|
||||
Song::Event &event = (*iter)->second;
|
||||
if ((frame > event.frame) && (frame < event.get_last_frame())) {
|
||||
// create two new events
|
||||
Song::Event left_event = event;
|
||||
Song::Event right_event = event;
|
||||
left_event.pattern = &model->new_pattern(event.pattern);
|
||||
left_event.pattern->set_length(frame - event.frame);
|
||||
right_event.pattern = &model->new_pattern(event.pattern);
|
||||
right_event.pattern->move_frames(0, event.frame - frame, -1);
|
||||
right_event.pattern->set_length(event.get_end() - frame);
|
||||
right_event.frame = frame;
|
||||
|
||||
new_selection.push_back(model->song.add_event(left_event));
|
||||
new_selection.push_back(model->song.add_event(right_event));
|
||||
|
||||
_pattern_erased(*iter);
|
||||
model->song.erase(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
selection = new_selection;
|
||||
invalidate_selection();
|
||||
|
||||
// cleanup
|
||||
model->delete_unused_patterns();
|
||||
}
|
||||
|
||||
void SongView::seek_to_mouse_cursor() {
|
||||
SongCursor cur(*this);
|
||||
cur.set_pos(cursor_x, cursor_y);
|
||||
|
@ -1003,6 +1041,7 @@ bool SongView::on_key_press_event(GdkEventKey* event) {
|
|||
edit_pattern(selection.front());
|
||||
return true;
|
||||
} break;
|
||||
case GDK_s: split_at_mouse_cursor(); return true;
|
||||
case GDK_p: seek_to_mouse_cursor(); return true;
|
||||
case GDK_m: toggle_mute_selection(); return true;
|
||||
case GDK_Left: navigate(-1,0); return true;
|
||||
|
|
|
@ -161,6 +161,7 @@ protected:
|
|||
int get_selection_end();
|
||||
void play_from_selection();
|
||||
void seek_to_mouse_cursor();
|
||||
void split_at_mouse_cursor();
|
||||
|
||||
bool can_resize_event(Song::iterator event, int x);
|
||||
void get_drag_offset(int &frame, int &track);
|
||||
|
|
Loading…
Reference in New Issue