bool FruityPerfInput::on_motion_notify_event(GdkEventMotion* a_ev, perfroll& ths) { long tick; int x = (int) a_ev->x; m_current_x = (int) a_ev->x; m_current_y = (int) a_ev->y; if ( m_adding_pressed ){ ths.convert_x( x, &tick ); if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){ long seq_length = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_length( ); tick = tick - (tick % seq_length); /*long min_tick = (tick < m_drop_tick) ? tick : m_drop_tick;*/ long length = seq_length; ths.m_mainperf->get_sequence( ths.m_drop_sequence ) ->grow_trigger( ths.m_drop_tick, tick, length); ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y); } } else if ( ths.m_moving || ths.m_growing ) { if ( ths.m_mainperf->is_active( ths.m_drop_sequence)) { ths.convert_x( x, &tick ); tick -= ths.m_drop_tick_trigger_offset; tick = tick - tick % ths.m_snap; if ( ths.m_moving ) { ths.m_mainperf->get_sequence( ths.m_drop_sequence ) ->move_selected_triggers_to( tick, true ); } if ( ths.m_growing ) { if ( ths.m_grow_direction ) ths.m_mainperf->get_sequence( ths.m_drop_sequence ) ->move_selected_triggers_to( tick, false, 0 ); else ths.m_mainperf->get_sequence( ths.m_drop_sequence ) ->move_selected_triggers_to( tick-1, false, 1 ); } ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y); } } updateMousePtr( ths ); return true; }
bool FruityPerfInput::on_button_press_event(GdkEventButton* a_ev, perfroll& ths) { ths.grab_focus( ); if ( ths.m_mainperf->is_active( ths.m_drop_sequence )) { ths.m_mainperf->get_sequence( ths.m_drop_sequence )->unselect_triggers( ); ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y); } ths.m_drop_x = (int) a_ev->x; ths.m_drop_y = (int) a_ev->y; m_current_x = (int) a_ev->x; m_current_y = (int) a_ev->y; ths.convert_xy( ths.m_drop_x, ths.m_drop_y, &ths.m_drop_tick, &ths.m_drop_sequence ); /* left mouse button */ if ( a_ev->button == 1) { on_left_button_pressed(a_ev, ths); } /* right mouse button */ if ( a_ev->button == 3 ) { on_right_button_pressed(a_ev, ths); } /* left-ctrl, or middle: split */ if ( a_ev->button == 2 ) { if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){ bool state = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_trigger_state( ths.m_drop_tick ); if ( state ) { ths.split_trigger(ths.m_drop_sequence, ths.m_drop_tick); } } } updateMousePtr( ths ); return true; }
bool FruityPerfInput::on_button_release_event(GdkEventButton* a_ev, perfroll& ths) { m_current_x = (int) a_ev->x; m_current_y = (int) a_ev->y; if ( a_ev->button == 1 || a_ev->button == 3 ) { m_adding_pressed = false; } ths.m_moving = false; ths.m_growing = false; m_adding_pressed = false; if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){ ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence ); ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y ); } updateMousePtr( ths ); return true; }
bool FruitySeqRollInput::on_motion_notify_event ( GdkEventMotion * a_ev, seqroll & sroll ) { sroll.m_current_x = (int)(a_ev->x + sroll.m_scroll_offset_x); sroll.m_current_y = (int)(a_ev->y + sroll.m_scroll_offset_y); if (sroll.m_moving_init) { sroll.m_moving_init = false; sroll.m_moving = true; } updateMousePtr(sroll); /* context sensitive mouse pointer... */ /* * Ctrl-left click drag on selected note(s) starts a copy/unselect/paste. * Don't begin the paste until mouse moves a few pixels, filter out * the unsteady hand. */ if ( sroll.m_is_drag_pasting_start && ( 6 <= abs(m_drag_paste_start_pos[0] - (long) a_ev->x) || 6 <= abs(m_drag_paste_start_pos[1] - (long) a_ev->y) ) ) { sroll.m_seq->copy_selected(); sroll.m_seq->unselect(); sroll.start_paste(); sroll.m_is_drag_pasting_start = false; sroll.m_is_drag_pasting = true; } int note; long tick; sroll.snap_y(&sroll.m_current_y); sroll.convert_xy(0, sroll.m_current_y, &tick, ¬e); sroll.m_seqkeys_wid->set_hint_key(note); if (sroll.m_selecting || sroll.m_moving || sroll.m_growing || sroll.m_paste) { if (sroll.m_moving || sroll.m_paste) sroll.snap_x(&sroll.m_current_x); sroll.draw_selection_on_window(); return true; } if (sroll.m_painting) { sroll.snap_x(&sroll.m_current_x); sroll.convert_xy(sroll.m_current_x, sroll.m_current_y, &tick, ¬e); sroll.m_seq->add_note(tick, sroll.m_note_length - 2, note, true); return true; } if (m_erase_painting) { sroll.convert_xy(sroll.m_current_x, sroll.m_current_y, &tick, ¬e); if ( sroll.m_seq->select_note_events ( tick, note, tick, note, sequence::e_would_select ) ) { /* remove only note under the cursor, leave selection intact */ sroll.m_seq->push_undo(); sroll.m_seq->select_note_events ( tick, note, tick, note, sequence::e_remove_one ); sroll.m_seq->set_dirty(); } } return false; }
bool FruitySeqRollInput::on_button_release_event ( GdkEventButton * a_ev, seqroll & sroll ) { long tick_s; long tick_f; int note_h; int note_l; int x, y, w, h; bool needs_update = false; sroll.m_current_x = (int)(a_ev->x + sroll.m_scroll_offset_x); sroll.m_current_y = (int)(a_ev->y + sroll.m_scroll_offset_y); sroll.snap_y(&sroll.m_current_y); if (sroll.m_moving || sroll.m_is_drag_pasting) sroll.snap_x(&sroll.m_current_x); int delta_x = sroll.m_current_x - sroll.m_drop_x; int delta_y = sroll.m_current_y - sroll.m_drop_y; long delta_tick; int delta_note; /* middle click, or ctrl-left click button up */ if (a_ev->button == 1 || a_ev->button == 2) { if (sroll.m_growing) { /* convert deltas into screen coordinates */ sroll.convert_xy(delta_x, delta_y, &delta_tick, &delta_note); sroll.m_seq->push_undo(); if (a_ev->state & GDK_SHIFT_MASK) sroll.m_seq->stretch_selected(delta_tick); else sroll.m_seq->grow_selected(delta_tick); needs_update = true; } } long int current_tick; int current_note; sroll.convert_xy ( sroll.m_current_x, sroll.m_current_y, ¤t_tick, ¤t_note ); /* * - ctrl-left click button up for select/drag copy/paste * - left click button up for ending a move of selected notes */ if (a_ev->button == 1) { m_adding = false; if (sroll.m_is_drag_pasting) { sroll.m_is_drag_pasting = false; sroll.m_is_drag_pasting_start = false; /* convert deltas into screen coordinates */ sroll.m_paste = false; sroll.m_seq->push_undo(); sroll.m_seq->paste_selected(current_tick, current_note); needs_update = true; } /* ctrl-left click but without movement - select a note */ if (sroll.m_is_drag_pasting_start) { sroll.m_is_drag_pasting_start = false; /* * If ctrl-left click without movement and if note under * cursor is selected, and ctrl is held and button-down didn't * just select one, then deselect the note. */ if ( ! sroll.m_justselected_one && sroll.m_seq->select_note_events ( current_tick, current_note, current_tick, current_note, sequence::e_is_selected ) && (a_ev->state & GDK_CONTROL_MASK)) { (void) sroll.m_seq->select_note_events ( current_tick, current_note, current_tick, current_note, sequence::e_deselect ); needs_update = true; } } sroll.m_justselected_one = false; /* clear flag on left button up */ if (sroll.m_moving) { delta_x -= sroll.m_move_snap_offset_x; /* adjust for snap */ /* convert deltas into screen coordinates */ sroll.convert_xy(delta_x, delta_y, &delta_tick, &delta_note); /* * Since delta_note was from delta_y, it will be flipped * ( delta_y[0] = note[127], etc.,so we have to adjust. */ delta_note = delta_note - (c_num_keys - 1); sroll.m_seq->push_undo(); sroll.m_seq->move_selected_notes(delta_tick, delta_note); needs_update = true; } } /* right click or leftctrl click button up for selection box */ if (a_ev->button == 3 || a_ev->button == 1) { if (sroll.m_selecting) { sroll.xy_to_rect ( sroll.m_drop_x, sroll.m_drop_y, sroll.m_current_x, sroll.m_current_y, &x, &y, &w, &h ); sroll.convert_xy(x, y, &tick_s, ¬e_h); sroll.convert_xy(x + w, y + h, &tick_f, ¬e_l); (void) sroll.m_seq->select_note_events ( tick_s, note_h, tick_f, note_l, sequence::e_toggle_selection ); needs_update = true; } } if (a_ev->button == 3) { m_erase_painting = false; } /* turn off */ sroll.m_selecting = false; sroll.m_moving = false; sroll.m_growing = false; sroll.m_paste = false; sroll.m_moving_init = false; sroll.m_painting = false; sroll.m_seq->unpaint_all(); updateMousePtr(sroll); /* context sensitive mouse pointer... */ if (needs_update) /* if they clicked, something changed */ { sroll.m_seq->set_dirty(); // redraw_events(); } return true; }
bool FruitySeqRollInput::on_button_press_event ( GdkEventButton * a_ev, seqroll & sroll ) { long tick_s; long tick_f; int note_h; int note_l; int norm_x, norm_y, snapped_x, snapped_y; bool needs_update = false; sroll.grab_focus(); snapped_x = norm_x = (int)(a_ev->x + sroll.m_scroll_offset_x); snapped_y = norm_y = (int)(a_ev->y + sroll.m_scroll_offset_y); sroll.snap_x(&snapped_x); sroll.snap_y(&snapped_y); sroll.m_current_y = sroll.m_drop_y = snapped_y; /* y is always snapped */ sroll.m_old.x = 0; /* reset box that holds dirty redraw spot */ sroll.m_old.y = 0; sroll.m_old.width = 0; sroll.m_old.height = 0; if (sroll.m_paste) /* ctrl-v pressed, waiting for click where to paste */ { sroll.convert_xy(snapped_x, snapped_y, &tick_s, ¬e_h); sroll.m_paste = false; sroll.m_seq->push_undo(); sroll.m_seq->paste_selected(tick_s, note_h); needs_update = true; } else { if (a_ev->button == 1) /* left mouse button */ { sroll.m_current_x = sroll.m_drop_x = norm_x; /* selection normal x */ /* turn x,y in to tick/note */ sroll.convert_xy(sroll.m_drop_x, sroll.m_drop_y, &tick_s, ¬e_h); if /* if not on top of event then add one... */ ( m_canadd && ! sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_would_select ) && ! (a_ev->state & GDK_CONTROL_MASK) ) { sroll.m_painting = true; /* start the paint job */ m_adding = true; /* adding, snapped x */ sroll.m_current_x = sroll.m_drop_x = snapped_x; sroll.convert_xy ( sroll.m_drop_x, sroll.m_drop_y, &tick_s, ¬e_h ); /* * Test if a note is already there; fake select, if so, no * add. */ if ( ! sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_would_select ) ) { /* add note, length = little less than snap */ sroll.m_seq->push_undo(); sroll.m_seq->add_note ( tick_s, sroll.m_note_length - 2, note_h, true ); needs_update = true; } } else /* selecting */ { if /* if under the cursor is not a selected note... */ ( ! sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_is_selected ) ) { if /* if clicking a note ... */ ( sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_would_select ) ) { /* ... unselect all if ctrl not held */ if (! (a_ev->state & GDK_CONTROL_MASK)) sroll.m_seq->unselect(); } else /* if clicking empty space ... */ { // ... unselect all if ctrl-shift not held if ( ! ( (a_ev->state & GDK_CONTROL_MASK) && (a_ev->state & GDK_SHIFT_MASK) ) ) sroll.m_seq->unselect(); } /* on direct click select only one event */ int numsel = sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_select_one ); /* prevent deselect in button_release() */ if (numsel) sroll.m_justselected_one = true; /* if nothing selected, start the selection box */ if (numsel == 0 && (a_ev->state & GDK_CONTROL_MASK)) sroll.m_selecting = true; needs_update = true; } /* if note under cursor is selected */ if ( sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_is_selected ) ) { bool right_mouse_handle = false; bool center_mouse_handle = false; { long drop_tick; int drop_note; sroll.convert_xy ( sroll.m_drop_x, sroll.m_drop_y, &drop_tick, &drop_note ); long start, end, note; if ( sroll.m_seq->intersectNotes ( drop_tick, drop_note, start, end, note ) && note == drop_note ) { long handle_size = clamp // 16 wide unless very small ( s_handlesize, 0, (end - start) / 3 ); if ( start <= drop_tick && drop_tick <= start + handle_size ) { center_mouse_handle = true; } else if ( end - handle_size <= drop_tick && drop_tick <= end ) { right_mouse_handle = true; } else { center_mouse_handle = true; } } } if /* grab/move the note */ ( center_mouse_handle && a_ev->button == 1 && ! (a_ev->state & GDK_CONTROL_MASK) ) { sroll.m_moving_init = true; needs_update = true; /* get the box that selected elements are in */ sroll.m_seq->get_selected_box ( &tick_s, ¬e_h, &tick_f, ¬e_l ); sroll.convert_tn_box_to_rect ( tick_s, tick_f, note_h, note_l, &sroll.m_selected.x, &sroll.m_selected.y, &sroll.m_selected.width, &sroll.m_selected.height ); /* save offset that we get from the snap above */ int adjusted_selected_x = sroll.m_selected.x; sroll.snap_x(&adjusted_selected_x); sroll.m_move_snap_offset_x = sroll.m_selected.x - adjusted_selected_x; /* align selection for drawing */ sroll.snap_x(&sroll.m_selected.x); sroll.m_current_x = sroll.m_drop_x = snapped_x; } else if /* ctrl left click when stuff is already selected */ ( a_ev->button == 1 && (a_ev->state & GDK_CONTROL_MASK) && sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_is_selected ) ) { sroll.m_is_drag_pasting_start = true; m_drag_paste_start_pos[0] = (long)a_ev->x; m_drag_paste_start_pos[1] = (long)a_ev->y; } if /* left click on the right handle - grow/resize event */ ( ( right_mouse_handle && a_ev->button == 1 && ! (a_ev->state & GDK_CONTROL_MASK) ) || a_ev->button == 2) { /* get the box that selected elements are in */ sroll.m_growing = true; sroll.m_seq->get_selected_box ( &tick_s, ¬e_h, &tick_f, ¬e_l ); sroll.convert_tn_box_to_rect ( tick_s, tick_f, note_h, note_l, &sroll.m_selected.x, &sroll.m_selected.y, &sroll.m_selected.width, &sroll.m_selected.height ); } } } } if (a_ev->button == 3) /* right click */ { sroll.m_current_x = sroll.m_drop_x = norm_x; /* selection normal x */ /* turn x,y in to tick/note */ sroll.convert_xy(sroll.m_drop_x, sroll.m_drop_y, &tick_s, ¬e_h); if /* erase event(s) under cursor if there is one */ ( sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_would_select ) ) { /* right ctrl click: remove all selected notes */ if (a_ev->state & GDK_CONTROL_MASK) { sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_select_one ); sroll.m_seq->push_undo(); sroll.m_seq->mark_selected(); sroll.m_seq->remove_marked(); } else { /* * right click: remove only the note under the cursor, * leave the selection intact. */ sroll.m_seq->push_undo(); sroll.m_seq->select_note_events ( tick_s, note_h, tick_s, note_h, sequence::e_remove_one ); } /* * hold down the right button, drag mouse around erasing notes: */ m_erase_painting = true; needs_update = true; /* repaint... we've changed the notes */ } else /* selecting */ { if (!(a_ev->state & GDK_CONTROL_MASK)) sroll.m_seq->unselect(); sroll.m_selecting = true; /* start the new selection box */ needs_update = true; } } } updateMousePtr(sroll); /* context sensative mouse pointer... */ if (needs_update) /* if they clicked, something changed */ { sroll.m_seq->set_dirty(); // redraw_events(); } return true; }