1
Fork 0

S splits a pattern at mouse cursor

This commit is contained in:
Leonard Ritter 2010-09-23 04:23:01 +02:00
parent c3cf05372d
commit 7f7ebbc862
6 changed files with 66 additions and 17 deletions

View File

@ -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).

View File

@ -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() {

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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);