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; }
void perftime::draw_background () { draw_rectangle(white_paint(), 0, 0, m_window_x, m_window_y); draw_line(black_paint(), 0, m_window_y - 1, m_window_x, m_window_y - 1); midipulse first_measure = m_tick_offset / m_measure_length; midipulse last_measure = first_measure + (m_window_x * m_perf_scale_x / m_measure_length) + 1; #ifdef USE_STAZED_EXTRAS float bar_draw = m_measure_length / float(m_perf_scale_x); int bar_skip = 1; if (bar_draw < 24) bar_skip = 4; if (bar_draw < 12) bar_skip = 8; if (bar_draw < 6) bar_skip = 16; if (bar_draw < 3) bar_skip = 32; if (bar_draw < .75) bar_skip = 64; #endif m_gc->set_foreground(grey()); /* draw vertical lines */ #ifdef USE_STAZED_EXTRAS for (midipulse i = first_measure; i < last_measure; i += bar_skip) { int x_pos = ((i * m_measure_length) - m_tick_offset) / m_perf_scale_x; #else for (midipulse i = first_measure; i < last_measure; ++i) { int x_pos = tick_to_pixel(i * m_measure_length); #endif char bar[8]; snprintf(bar, sizeof(bar), "%ld", i + 1); /* bar numbers */ draw_line(x_pos, 0, x_pos, m_window_y); /* beat */ render_string(x_pos + 2, 0, bar, font::BLACK, true); } midipulse left = tick_to_pixel(perf().get_left_tick()); midipulse right = tick_to_pixel(perf().get_right_tick()); if (left >= 0 && left <= m_window_x) /* draw L marker */ { draw_rectangle(black_paint(), left, m_window_y - 9, 7, 10); render_string(left + 1, 9, "L", font::WHITE, true); } if (right >= 0 && right <= m_window_x) /* draw R marker */ { draw_rectangle(black_paint(), right - 6, m_window_y - 9, 7, 10); render_string(right - 6 + 1, 9, "R", font::WHITE, true); } } /** * Implement the button-press event to set the L and R ticks. Added * functionality to try to set the start-tick if ctrl-left-click is pressed. * * \param p0 * The button event. * * \return * Always returns true. */ bool perftime::on_button_press_event (GdkEventButton * p0) { midipulse tick = pixel_to_tick(long(p0->x)); tick -= tick % m_snap; /** * Why is setting the start-tick disabled? We re-enable it and see if it * works. To our surprise, it works, but it sticks between stop/pause and * the next playback in the performance editor. We added a feature where * stop sets the start-tick to the left tick (or the beginning tick). */ if (SEQ64_CLICK_MIDDLE(p0->button)) { perf().set_start_tick(tick); } else if (SEQ64_CLICK_LEFT(p0->button)) { if (is_ctrl_key(p0)) perf().set_start_tick(tick); else perf().set_left_tick(tick); } else if (SEQ64_CLICK_RIGHT(p0->button)) { perf().set_right_tick(tick + m_snap); } enqueue_draw(); return true; }
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; }