#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
}
void
-Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemType item_type)
+Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
+
/* in object/audition/timefx/gain-automation mode,
any button press sets the selection if the object
can be selected. this is a bit of hack, because
/* 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;
}
}
switch (item_type) {
case RegionItem:
+ if (eff_mouse_mode == MouseDraw) {
+ break;
+ }
if (press) {
if (eff_mouse_mode != MouseRange) {
_mouse_changed_selection = set_selected_regionview_from_click (press, op);
/* 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;
+
+ case GainLineItem:
+ if (eff_mouse_mode != MouseRange) {
+ AutomationLine* argl = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
+
+ std::list<Selectable*> selectables;
+ uint32_t before, after;
+ framecnt_t const where = (framecnt_t) floor (event->button.x * samples_per_pixel) - clicked_regionview->region ()->position ();
+
+ if (!argl || !argl->control_points_adjacent (where, before, after)) {
+ break;
+ }
+
+ selectables.push_back (argl->nth (before));
+ selectables.push_back (argl->nth (after));
+
+ switch (op) {
+ case Selection::Set:
+ if (press) {
+ selection->set (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+ case Selection::Add:
+ if (press) {
+ selection->add (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+ case Selection::Toggle:
+ if (press) {
+ selection->toggle (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+
+ case Selection::Extend:
+ /* XXX */
+ break;
+ }
+ }
+ break;
+
+ case AutomationLineItem:
+ 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 (mx * samples_per_pixel);
+
+ if (!al || !al->control_points_adjacent (where, before, after)) {
+ break;
+ }
+
+ selectables.push_back (al->nth (before));
+ selectables.push_back (al->nth (after));
+
+ switch (op) {
+ case Selection::Set:
+ if (press) {
+ selection->set (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+ case Selection::Add:
+ if (press) {
+ selection->add (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+ case Selection::Toggle:
+ if (press) {
+ selection->toggle (selectables);
+ _mouse_changed_selection = true;
+ }
+ break;
+
+ case Selection::Extend:
+ /* XXX */
+ break;
+ }
}
break;
break;
case AutomationTrackItem:
- set_selected_track_as_side_effect (op);
+ 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:
new TempoMarkerDrag (
this,
item,
- Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
+ ArdourKeyboard::indicates_copy (event->button.state)
),
event
);
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)) {
+ _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);
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:
mouse_add_new_marker (where, true);
}
return true;
-
case TempoBarItem:
+ case TempoCurveItem:
if (!_dragging_playhead) {
snap_to_with_modifier (where, event);
mouse_add_new_tempo_event (where);
{
ControlPoint* cp;
ArdourMarker * marker;
+ MeterMarker* m_marker = 0;
+ TempoMarker* t_marker = 0;
double fraction;
bool ret = true;
switch (item_type) {
case ControlPointItem:
- if (mouse_mode == MouseDraw || mouse_mode == MouseObject) {
+ if (mouse_mode == MouseDraw || mouse_mode == MouseObject || mouse_mode == MouseContent) {
cp = static_cast<ControlPoint*>(item->get_data ("control_point"));
cp->show ();
}
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
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