bool FruityPerfInput::on_button_press_event (GdkEventButton * ev, perfroll & roll) { bool result = false; perform & p = roll.perf(); roll.grab_focus(); int & dropseq = roll.m_drop_sequence; /* reference needed */ sequence * seq = p.get_sequence(dropseq); if (p.is_active(dropseq)) { seq->unselect_triggers(); roll.draw_all(); } else { return false; } roll.m_drop_x = int(ev->x); roll.m_drop_y = int(ev->y); m_current_x = int(ev->x); m_current_y = int(ev->y); roll.convert_xy /* side-effects */ ( roll.m_drop_x, roll.m_drop_y, roll.m_drop_tick, dropseq ); if (SEQ64_CLICK_LEFT(ev->button)) { result = on_left_button_pressed(ev, roll); } else if (SEQ64_CLICK_RIGHT(ev->button)) { result = on_right_button_pressed(ev, roll); } else if (SEQ64_CLICK_MIDDLE(ev->button)) /* left-ctrl???, middle */ { /* * Implements some Stazed fixes now. */ if (p.is_active(dropseq)) { midipulse droptick = roll.m_drop_tick; droptick -= droptick % roll.m_snap; /* stazed fix: grid snap */ bool state = seq->get_trigger_state(droptick); if (state) /* trigger click, split it */ { roll.split_trigger(dropseq, droptick); result = true; } else /* track click, paste trig */ { p.push_trigger_undo(dropseq); seq->paste_trigger(droptick); } } } update_mouse_pointer(roll); return result; }
bool FruityPerfInput::on_button_release_event (GdkEventButton * ev, perfroll & roll) { bool result = false; m_current_x = int(ev->x); m_current_y = int(ev->y); perform & p = roll.perf(); roll.m_moving = false; roll.m_growing = false; set_adding_pressed(false); if (p.is_active(roll.m_drop_sequence)) roll.draw_all(); update_mouse_pointer(roll); return result; }
bool Seq24PerfInput::on_button_release_event (GdkEventButton * ev, perfroll & roll) { bool result = false; if (SEQ64_CLICK_LEFT(ev->button)) { if (is_adding()) set_adding_pressed(false); } else if (SEQ64_CLICK_RIGHT(ev->button)) { /* * Minor new feature. If the Super (Mod4, Windows) key is * pressed when release, keep the adding-state in force. One * can then use the unadorned left-click key to add material. Right * click to reset the adding mode. This feature is enabled only * if allowed by Options / Mouse (but is true by default). * See the same code in seq24seqroll.cpp. */ bool addmode_exit = ! rc().allow_mod4_mode(); if (! addmode_exit) addmode_exit = ! is_super_key(ev); /* Mod4 held? */ if (addmode_exit) { set_adding_pressed(false); activate_adding(false, roll); } } perform & p = roll.perf(); roll.m_moving = roll.m_growing = false; set_adding_pressed(false); m_effective_tick = 0; if (p.is_active(roll.m_drop_sequence)) { roll.draw_all(); } return result; }
bool Seq24PerfInput::on_button_press_event (GdkEventButton * ev, perfroll & roll) { bool result = false; perform & p = roll.perf(); int & dropseq = roll.m_drop_sequence; sequence * seq = p.get_sequence(dropseq); bool dropseq_active = p.is_active(dropseq); roll.grab_focus(); if (dropseq_active) { seq->unselect_triggers(); roll.draw_all(); } roll.m_drop_x = int(ev->x); roll.m_drop_y = int(ev->y); roll.convert_drop_xy(); /* affects dropseq */ seq = p.get_sequence(dropseq); dropseq_active = p.is_active(dropseq); if (! dropseq_active) return false; /* * EXPERIMENTAL. * Let's make better use of the Ctrl key here. First, let Ctrl-Left be * handled exactly like the Middle click, then bug out. * * Note that this middle-click code ought to be folded into a function. */ if (is_ctrl_key(ev)) { if (SEQ64_CLICK_LEFT(ev->button)) { bool state = seq->get_trigger_state(roll.m_drop_tick); if (state) { roll.split_trigger(dropseq, roll.m_drop_tick); } else { p.push_trigger_undo(dropseq); seq->paste_trigger(roll.m_drop_tick); } } return true; } if (SEQ64_CLICK_LEFT(ev->button)) { midipulse droptick = roll.m_drop_tick; if (is_adding()) /* add new note if nothing selected */ { set_adding_pressed(true); midipulse seqlength = seq->get_length(); bool state = seq->get_trigger_state(droptick); if (state) { p.push_trigger_undo(dropseq); /* stazed fix */ seq->del_trigger(droptick); } else { droptick -= (droptick % seqlength); /* snap */ p.push_trigger_undo(dropseq); /* stazed fix */ seq->add_trigger(droptick, seqlength); roll.draw_all(); } result = true; } else { /* * Set this flag to tell on_motion_notify() to call * p.push_trigger_undo(). */ roll.m_have_button_press = seq->select_trigger(droptick); midipulse tick0 = seq->selected_trigger_start(); midipulse tick1 = seq->selected_trigger_end(); int wscalex = s_perfroll_size_box_click_w * c_perf_scale_x; int ydrop = roll.m_drop_y % c_names_y; if ( droptick >= tick0 && droptick <= (tick0 + wscalex) && ydrop <= s_perfroll_size_box_click_w + 1 ) { roll.m_growing = true; roll.m_grow_direction = true; roll.m_drop_tick_trigger_offset = droptick - seq->selected_trigger_start(); } else if ( droptick >= (tick1 - wscalex) && droptick <= tick1 && ydrop >= c_names_y - s_perfroll_size_box_click_w - 1 ) { roll.m_growing = true; roll.m_grow_direction = false; roll.m_drop_tick_trigger_offset = droptick - seq->selected_trigger_end(); } else { roll.m_moving = true; roll.m_drop_tick_trigger_offset = droptick - seq->selected_trigger_start(); } roll.draw_all(); } } else if (SEQ64_CLICK_RIGHT(ev->button)) { activate_adding(true, roll); // Should we add this? // result = true; } else if (SEQ64_CLICK_MIDDLE(ev->button)) /* split */ { /* * The middle click in seq24 interaction mode is either for splitting * the triggers or for setting the paste location of copy/paste. */ bool state = seq->get_trigger_state(roll.m_drop_tick); if (state) { roll.split_trigger(dropseq, roll.m_drop_tick); result = true; } else { p.push_trigger_undo(dropseq); seq->paste_trigger(roll.m_drop_tick); // Should we add this? // result = true; } } return result; }
bool Seq24PerfInput::on_motion_notify_event (GdkEventMotion * ev, perfroll & roll) { bool result = false; int x = int(ev->x); perform & p = roll.perf(); int dropseq = roll.m_drop_sequence; sequence * seq = p.get_sequence(dropseq); if (! p.is_active(dropseq)) { return false; } if (is_adding() && is_adding_pressed()) { midipulse seqlength = seq->get_length(); midipulse tick; roll.convert_x(x, tick); tick -= (tick % seqlength); midipulse length = seqlength; seq->grow_trigger(roll.m_drop_tick, tick, length); roll.draw_all(); result = true; } else if (roll.m_moving || roll.m_growing) { /* * This code is necessary to insure that there is no push unless * we have a motion notification. */ if (roll.m_have_button_press) { p.push_trigger_undo(dropseq); roll.m_have_button_press = false; } midipulse tick; roll.convert_x(x, tick); tick -= roll.m_drop_tick_trigger_offset; tick -= tick % roll.m_snap; if (roll.m_moving) { seq->move_selected_triggers_to(tick, true); result = true; } if (roll.m_growing) { if (roll.m_grow_direction) { seq->move_selected_triggers_to ( tick, false, triggers::GROW_START ); } else { seq->move_selected_triggers_to ( tick - 1, false, triggers::GROW_END); } result = true; } roll.draw_all(); } return result; }
bool FruityPerfInput::on_left_button_pressed (GdkEventButton * ev, perfroll & roll) { bool result = false; perform & p = roll.perf(); int dropseq = roll.m_drop_sequence; sequence * seq = p.get_sequence(dropseq); if (is_ctrl_key(ev)) { if (p.is_active(dropseq)) { midipulse droptick = roll.m_drop_tick; droptick -= droptick % roll.m_snap; /* stazed: grid snap */ bool state = seq->get_trigger_state(droptick); if (state) { roll.split_trigger(dropseq, droptick); result = true; } else /* track click, paste trig */ { p.push_trigger_undo(dropseq); seq->paste_trigger(droptick); } } } else /* add a new note if we didn't select anything */ { midipulse droptick = roll.m_drop_tick; set_adding_pressed(true); if (p.is_active(dropseq)) { midipulse seqlength = seq->get_length(); bool state = seq->get_trigger_state(droptick); if (state) /* resize or move event based on where clicked */ { set_adding_pressed(false); /* * Set the flag that tells the motion-notify callback to call * push_trigger_undo(). */ roll.m_have_button_press = seq->select_trigger(droptick); midipulse starttick = seq->selected_trigger_start(); midipulse endtick = seq->selected_trigger_end(); int wscalex = s_perfroll_size_box_click_w * c_perf_scale_x; int ydrop = roll.m_drop_y % c_names_y; if ( droptick >= starttick && droptick <= (starttick + wscalex) && ydrop <= (s_perfroll_size_box_click_w + 1) ) { /* clicked left side: grow/shrink left side */ roll.m_growing = true; roll.m_grow_direction = true; roll.m_drop_tick_trigger_offset = roll.m_drop_tick - seq->selected_trigger_start(); } else if ( droptick >= (endtick - wscalex) && droptick <= endtick && ydrop >= (c_names_y - s_perfroll_size_box_click_w - 1) ) { /* clicked right side: grow/shrink right side */ roll.m_growing = true; roll.m_grow_direction = false; roll.m_drop_tick_trigger_offset = roll.m_drop_tick - seq->selected_trigger_end(); } else /* clicked in the middle - move it */ { roll.m_moving = true; roll.m_drop_tick_trigger_offset = roll.m_drop_tick - seq->selected_trigger_start(); } roll.draw_all(); } else /* add a trigger */ { droptick -= (droptick % seqlength); /* snap to seqlength */ p.push_trigger_undo(); seq->add_trigger(droptick, seqlength); result = true; roll.draw_all(); } } } return result; }