#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/utils.h"
-#include "gtkmm2ext/tearoff.h"
#include "canvas/canvas.h"
#include "ardour/types.h"
#include "actions.h"
+#include "ardour_ui.h"
#include "editor.h"
#include "time_axis_view.h"
#include "audio_time_axis.h"
#include "verbose_cursor.h"
#include "note.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
switch (mouse_mode) {
case MouseRange:
selection->clear_objects ();
- selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
+ selection->clear_midi_notes ();
break;
case MouseObject:
selection->clear_time ();
- selection->clear_tracks ();
- selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
+ selection->clear_midi_notes ();
break;
case MouseDraw:
/* Clear regions, but not time or tracks, since that
/* almost no selection action on modified button-2 or button-3 events */
- if (item_type != RegionItem && event->button.button != 2) {
+ if ((item_type != RegionItem && event->button.button != 2)
+ /* for selection of control points prior to delete (shift-right click) */
+ && !(item_type == ControlPointItem && event->button.button == 3 && event->type == GDK_BUTTON_PRESS)) {
return;
}
}
/* for object/track exclusivity, we don't call set_selected_track_as_side_effect (op); */
if (eff_mouse_mode != MouseRange) {
- _mouse_changed_selection |= set_selected_control_point_from_click (press, op);
+ if (event->button.button != 3) {
+ _mouse_changed_selection |= set_selected_control_point_from_click (press, op);
+ } else {
+ _mouse_changed_selection |= set_selected_control_point_from_click (press, Selection::Set);
+ }
}
break;
if (eff_mouse_mode != MouseRange) {
AutomationLine* al = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
std::list<Selectable*> selectables;
+ double mx = event->button.x;
+ double my = event->button.y;
+
+ al->grab_item().canvas_to_item (mx, my);
+
uint32_t before, after;
- framecnt_t const where = (framecnt_t) floor (event->button.x * samples_per_pixel);
+ framecnt_t const where = (framecnt_t) floor (mx * samples_per_pixel);
if (!al || !al->control_points_adjacent (where, before, after)) {
break;
break;
case AutomationTrackItem:
- if (eff_mouse_mode != MouseDraw) {
+ if (eff_mouse_mode != MouseDraw && op == Selection::Set) {
set_selected_track_as_side_effect (op);
}
break;
+ case NoteItem:
+ if (press && event->button.button == 3) {
+ NoteBase* cnote = reinterpret_cast<NoteBase*> (item->get_data ("notebase"));
+ assert (cnote);
+ if (cnote->region_view().selection_size() == 0 || !cnote->selected()) {
+ selection->clear_points();
+ cnote->region_view().unique_select (cnote);
+ /* we won't get the release, so store the selection change now */
+ begin_reversible_selection_op (X_("Button 3 Note Selection"));
+ commit_reversible_selection_op ();
+ }
+ }
+ break;
+
default:
break;
}
case TempoMarkerItem:
{
- _drags->set (
- new TempoMarkerDrag (
- this,
- item,
- Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
- ),
- event
- );
+ if (ArdourKeyboard::indicates_constraint (event->button.state)) {
+ _drags->set (
+ new TempoEndDrag (
+ this,
+ item
+ ),
+ event
+ );
+ } else {
+ _drags->set (
+ new TempoMarkerDrag (
+ this,
+ item,
+ ArdourKeyboard::indicates_copy (event->button.state)
+ ),
+ event
+ );
+ }
+
return true;
}
new MeterMarkerDrag (
this,
item,
- Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
+ ArdourKeyboard::indicates_copy (event->button.state)
),
event
);
case MarkerBarItem:
case TempoBarItem:
+ case TempoCurveItem:
case MeterBarItem:
case TimecodeRulerItem:
case SamplesRulerItem:
case MinsecRulerItem:
case BBTRulerItem:
- if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+ if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)
+ && !ArdourKeyboard::indicates_constraint (event->button.state)) {
_drags->set (new CursorDrag (this, *playhead_cursor, false), event);
+ } else if (ArdourKeyboard::indicates_constraint (event->button.state)
+ && Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) {
+ _drags->set (new TempoTwistDrag (this, item), event);
+ } else if (ArdourKeyboard::indicates_constraint (event->button.state)) {
+ _drags->set (new BBTRulerDrag (this, item), event);
}
return true;
break;
}
/* click on a normal region view */
- if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
+ if (ArdourKeyboard::indicates_copy (event->button.state)) {
add_region_copy_drag (item, event, clicked_regionview);
} else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
add_region_brush_drag (item, event, clicked_regionview);
if (!prev) {
_drags->set (new RegionCreateDrag (this, item, parent), event);
} else {
- prev->set_length (t - prev->position ());
+ prev->set_length (t - prev->position (), get_grid_music_divisions (event->button.state));
}
}
} else {
case MouseObject:
switch (item_type) {
case RegionItem:
- if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
+ if (ArdourKeyboard::indicates_copy (event->button.state)) {
add_region_copy_drag (item, event, clicked_regionview);
} else {
add_region_drag (item, event, clicked_regionview);
return true;
}
- //not rolling, range mode click + join_play_range : locate the PH here
- if ( !_drags->active () && _session && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && UIConfiguration::instance().get_follow_edits() && !_session->config.get_external_sync() ) {
- framepos_t where = canvas_event_sample (event);
- snap_to(where);
- _session->request_locate (where, false);
+ /* not rolling, effectively in range mode, follow edits enabled (likely
+ * to start range drag), not in a fade handle (since that means we are
+ * not starting a range drag): locate the PH here
+ */
+
+ if ((item_type != FadeInHandleItem) &&
+ (item_type != FadeOutHandleItem) &&
+ !_drags->active () &&
+ _session &&
+ !_session->transport_rolling() &&
+ (effective_mouse_mode() == MouseRange) &&
+ UIConfiguration::instance().get_follow_edits() &&
+ !_session->config.get_external_sync()) {
+
+ MusicFrame where (canvas_event_sample (event), 0);
+ snap_to (where);
+ _session->request_locate (where.frame, false);
}
switch (event->button.button) {
bool
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
- framepos_t where = canvas_event_sample (event);
+ MusicFrame where (canvas_event_sample (event), 0);
AutomationTimeAxisView* atv = 0;
_press_cursor_ctx.reset();
case RegionItem:
show_region_properties ();
break;
-
case TempoMarkerItem: {
ArdourMarker* marker;
TempoMarker* tempo_marker;
case TransportMarkerBarItem:
case CdMarkerBarItem:
case TempoBarItem:
+ case TempoCurveItem:
case MeterBarItem:
case VideoBarItem:
case TimecodeRulerItem:
case SamplesRulerItem:
case MinsecRulerItem:
case BBTRulerItem:
- popup_ruler_menu (where, item_type);
+ popup_ruler_menu (where.frame, item_type);
break;
case MarkerItem:
case MarkerBarItem:
if (!_dragging_playhead) {
snap_to_with_modifier (where, event, RoundNearest, true);
- mouse_add_new_marker (where);
+ mouse_add_new_marker (where.frame);
}
return true;
if (!_dragging_playhead) {
// if we get here then a dragged range wasn't done
snap_to_with_modifier (where, event, RoundNearest, true);
- mouse_add_new_marker (where, true);
+ mouse_add_new_marker (where.frame, true);
}
return true;
-
case TempoBarItem:
+ case TempoCurveItem:
if (!_dragging_playhead) {
snap_to_with_modifier (where, event);
- mouse_add_new_tempo_event (where);
+ mouse_add_new_tempo_event (where.frame);
}
return true;
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
if (atv) {
- atv->add_automation_event (event, where, event->button.y, with_guard_points);
+ atv->add_automation_event (event, where.frame, event->button.y, with_guard_points);
}
return true;
break;
{
ControlPoint* cp;
ArdourMarker * marker;
+ MeterMarker* m_marker = 0;
+ TempoMarker* t_marker = 0;
double fraction;
bool ret = true;
}
entered_marker = marker;
marker->set_color_rgba (UIConfiguration::instance().color ("entered marker"));
- // fall through
+ break;
+
case MeterMarkerItem:
+ if ((m_marker = static_cast<MeterMarker *> (item->get_data ("marker"))) == 0) {
+ break;
+ }
+ entered_marker = m_marker;
+ if (m_marker->meter().position_lock_style() == MusicTime) {
+ m_marker->set_color_rgba (UIConfiguration::instance().color ("meter marker"));
+ } else {
+ m_marker->set_color_rgba (UIConfiguration::instance().color ("meter marker music"));
+ }
+ break;
+
case TempoMarkerItem:
+ if ((t_marker = static_cast<TempoMarker *> (item->get_data ("marker"))) == 0) {
+ break;
+ }
+ entered_marker = t_marker;
+ if (t_marker->tempo().position_lock_style() == MusicTime) {
+ t_marker->set_color_rgba (UIConfiguration::instance().color ("tempo marker"));
+ } else {
+ t_marker->set_color_rgba (UIConfiguration::instance().color ("tempo marker music"));
+ }
break;
case FadeInHandleItem:
{
AutomationLine* al;
ArdourMarker *marker;
+ TempoMarker *t_marker;
+ MeterMarker *m_marker;
Location *loc;
bool is_start;
bool ret = true;
if ((loc = find_location_from_marker (marker, is_start)) != 0) {
location_flags_changed (loc);
}
- // fall through
+ break;
+
case MeterMarkerItem:
+ if ((m_marker = static_cast<MeterMarker *> (item->get_data ("marker"))) == 0) {
+ break;
+ }
+ entered_marker = 0;
+ if (m_marker->meter().position_lock_style() == MusicTime) {
+ m_marker->set_color_rgba (UIConfiguration::instance().color ("meter marker music"));
+ } else {
+ m_marker->set_color_rgba (UIConfiguration::instance().color ("meter marker"));
+ }
+ break;
+
case TempoMarkerItem:
+ if ((t_marker = static_cast<TempoMarker *> (item->get_data ("marker"))) == 0) {
+ break;
+ }
+ entered_marker = 0;
+ if (t_marker->tempo().position_lock_style() == MusicTime) {
+ t_marker->set_color_rgba (UIConfiguration::instance().color ("tempo marker music"));
+ } else {
+ t_marker->set_color_rgba (UIConfiguration::instance().color ("tempo marker"));
+ }
break;
case FadeInTrimHandleItem:
void
Editor::note_edit_done (int r, EditNoteDialog* d)
{
+ begin_reversible_command (_("edit note(s)"));
+
d->done (r);
delete d;
+
+ commit_reversible_command();
+}
+
+void
+Editor::edit_region (RegionView* rv)
+{
+ if (UIConfiguration::instance().get_use_double_click_to_zoom_to_selection()) {
+ temporal_zoom_selection (Both);
+ } else {
+ rv->show_region_editor ();
+ }
}
void
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
- if (!rtv->hidden()) {
+ if (rtv && !rtv->hidden()) {
if (*high < rtv->order()) {
*high = rtv->order ();
break;
case 2:
- begin_reversible_command (_("End point trim"));
+ begin_reversible_command (_("end point trim"));
if (selection->selected (rv)) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
- if (rtv == 0 || !rtv->is_track()) {
+ if (!rtv || !rtv->is_track()) {
return;
}
selection->clear ();
}
- reset_focus ();
+ ARDOUR_UI::instance()->reset_focus (&contents());
}
/** Update _join_object_range_state which indicate whether we are over the top
if (entered_regionview) {
+ //ToDo: there is currently a bug here(?)
+ //when we are inside a region fade handle, it acts as though we are in range mode because it is in the top half of the region
+ //can it be fixed here?
+
ArdourCanvas::Duple const item_space = entered_regionview->get_canvas_group()->canvas_to_item (ArdourCanvas::Duple (0, y));
double const c = item_space.y / entered_regionview->height();