2005-09-25 14:42:24 -04:00
|
|
|
/*
|
2009-10-14 12:10:01 -04:00
|
|
|
Copyright (C) 2000-2001 Paul Davis
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2006-07-23 08:03:19 -04:00
|
|
|
#include <cassert>
|
2005-09-25 14:42:24 -04:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <cmath>
|
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include <algorithm>
|
2013-04-04 00:32:52 -04:00
|
|
|
#include <bitset>
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "pbd/error.h"
|
2009-07-28 16:51:28 -04:00
|
|
|
#include "pbd/enumwriter.h"
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "pbd/memento_command.h"
|
|
|
|
#include "pbd/basename.h"
|
2010-03-02 13:05:26 -05:00
|
|
|
#include "pbd/stateful_diff_command.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2011-03-03 22:10:48 -05:00
|
|
|
#include "gtkmm2ext/bindings.h"
|
|
|
|
#include "gtkmm2ext/utils.h"
|
|
|
|
#include "gtkmm2ext/tearoff.h"
|
|
|
|
|
2013-04-04 00:32:52 -04:00
|
|
|
#include "canvas/canvas.h"
|
|
|
|
|
|
|
|
#include "ardour/audioregion.h"
|
|
|
|
#include "ardour/operations.h"
|
|
|
|
#include "ardour/playlist.h"
|
|
|
|
#include "ardour/profile.h"
|
|
|
|
#include "ardour/region_factory.h"
|
|
|
|
#include "ardour/route.h"
|
|
|
|
#include "ardour/session.h"
|
|
|
|
#include "ardour/types.h"
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "ardour_ui.h"
|
2009-07-28 16:51:28 -04:00
|
|
|
#include "actions.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "editor.h"
|
|
|
|
#include "time_axis_view.h"
|
|
|
|
#include "audio_time_axis.h"
|
2006-08-01 13:19:38 -04:00
|
|
|
#include "audio_region_view.h"
|
2007-03-18 02:07:08 -04:00
|
|
|
#include "midi_region_view.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "marker.h"
|
|
|
|
#include "streamview.h"
|
|
|
|
#include "region_gain_line.h"
|
|
|
|
#include "automation_time_axis.h"
|
2007-07-06 23:19:04 -04:00
|
|
|
#include "control_point.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "prompter.h"
|
|
|
|
#include "selection.h"
|
|
|
|
#include "keyboard.h"
|
|
|
|
#include "editing.h"
|
|
|
|
#include "rgb_macros.h"
|
2008-12-18 12:46:28 -05:00
|
|
|
#include "control_point_dialog.h"
|
2009-05-30 14:25:59 -04:00
|
|
|
#include "editor_drag.h"
|
2010-08-04 11:41:55 -04:00
|
|
|
#include "automation_region_view.h"
|
2010-08-13 22:00:50 -04:00
|
|
|
#include "edit_note_dialog.h"
|
2010-11-16 09:53:16 -05:00
|
|
|
#include "mouse_cursors.h"
|
|
|
|
#include "editor_cursors.h"
|
2011-05-02 09:38:16 -04:00
|
|
|
#include "verbose_cursor.h"
|
2013-04-04 00:32:52 -04:00
|
|
|
#include "note.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
#include "i18n.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace ARDOUR;
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
using namespace PBD;
|
2005-09-25 14:42:24 -04:00
|
|
|
using namespace Gtk;
|
|
|
|
using namespace Editing;
|
2009-12-04 17:51:32 -05:00
|
|
|
using Gtkmm2ext::Keyboard;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2007-11-07 20:40:25 -05:00
|
|
|
bool
|
2010-09-17 14:20:37 -04:00
|
|
|
Editor::mouse_frame (framepos_t& where, bool& in_track_canvas) const
|
2007-11-07 20:40:25 -05:00
|
|
|
{
|
2012-03-09 12:15:25 -05:00
|
|
|
/* gdk_window_get_pointer() has X11's XQueryPointer semantics in that it only
|
|
|
|
pays attentions to subwindows. this means that menu windows are ignored, and
|
|
|
|
if the pointer is in a menu, the return window from the call will be the
|
|
|
|
the regular subwindow *under* the menu.
|
|
|
|
|
|
|
|
this matters quite a lot if the pointer is moving around in a menu that overlaps
|
|
|
|
the track canvas because we will believe that we are within the track canvas
|
|
|
|
when we are not. therefore, we track enter/leave events for the track canvas
|
|
|
|
and allow that to override the result of gdk_window_get_pointer().
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!within_track_canvas) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-11-07 20:40:25 -05:00
|
|
|
int x, y;
|
2013-04-12 11:09:49 -04:00
|
|
|
Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->_track_canvas->get_window();
|
2008-04-11 10:06:50 -04:00
|
|
|
|
|
|
|
if (!canvas_window) {
|
|
|
|
return false;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2013-04-12 11:09:49 -04:00
|
|
|
Glib::RefPtr<const Gdk::Window> pointer_window = Gdk::Display::get_default()->get_window_at_pointer (x, y);
|
2007-11-07 20:40:25 -05:00
|
|
|
|
2013-04-12 11:09:49 -04:00
|
|
|
if (!pointer_window) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-21 11:12:57 -04:00
|
|
|
if (pointer_window != canvas_window) {
|
2007-11-07 20:40:25 -05:00
|
|
|
in_track_canvas = false;
|
2013-04-04 00:32:52 -04:00
|
|
|
return false;
|
2007-11-07 20:40:25 -05:00
|
|
|
}
|
|
|
|
|
2013-04-12 11:09:49 -04:00
|
|
|
in_track_canvas = true;
|
|
|
|
|
2007-11-07 20:40:25 -05:00
|
|
|
GdkEvent event;
|
|
|
|
event.type = GDK_BUTTON_RELEASE;
|
2013-04-12 11:09:49 -04:00
|
|
|
event.button.x = x;
|
|
|
|
event.button.y = y;
|
|
|
|
|
2014-02-26 08:43:53 -05:00
|
|
|
where = window_event_sample (&event, 0, 0);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-11-07 20:40:25 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-09-17 14:20:37 -04:00
|
|
|
framepos_t
|
2014-02-26 08:43:53 -05:00
|
|
|
Editor::window_event_sample (GdkEvent const * event, double* pcx, double* pcy) const
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2014-05-20 23:08:15 -04:00
|
|
|
ArdourCanvas::Duple d;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-05-20 23:08:15 -04:00
|
|
|
if (!gdk_event_get_coords (event, &d.x, &d.y)) {
|
2013-04-12 11:09:49 -04:00
|
|
|
return 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2013-04-12 11:09:49 -04:00
|
|
|
/* event coordinates are in window units, so convert to canvas
|
2013-04-11 20:19:22 -04:00
|
|
|
*/
|
2013-04-04 00:32:52 -04:00
|
|
|
|
2014-05-20 23:08:15 -04:00
|
|
|
d = _track_canvas->window_to_canvas (d);
|
2013-04-12 11:09:49 -04:00
|
|
|
|
|
|
|
if (pcx) {
|
2013-04-11 20:19:22 -04:00
|
|
|
*pcx = d.x;
|
2013-04-12 11:09:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pcy) {
|
2013-04-11 20:19:22 -04:00
|
|
|
*pcy = d.y;
|
2013-04-12 11:09:49 -04:00
|
|
|
}
|
|
|
|
|
2013-04-12 11:15:45 -04:00
|
|
|
return pixel_to_sample (d.x);
|
2013-04-12 11:09:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
framepos_t
|
2014-02-26 08:43:53 -05:00
|
|
|
Editor::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) const
|
2013-04-12 11:09:49 -04:00
|
|
|
{
|
|
|
|
double x;
|
|
|
|
double y;
|
|
|
|
|
|
|
|
/* event coordinates are already in canvas units */
|
|
|
|
|
|
|
|
if (!gdk_event_get_coords (event, &x, &y)) {
|
|
|
|
cerr << "!NO c COORDS for event type " << event->type << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pcx) {
|
|
|
|
*pcx = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pcy) {
|
|
|
|
*pcy = y;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2014-03-20 13:29:29 -04:00
|
|
|
/* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel
|
2005-09-25 14:42:24 -04:00
|
|
|
position is negative (as can be the case with motion events in particular),
|
|
|
|
the frame location is always positive.
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-03-20 13:29:29 -04:00
|
|
|
return pixel_to_sample_from_event (x);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2010-09-22 11:21:06 -04:00
|
|
|
void
|
|
|
|
Editor::set_current_trimmable (boost::shared_ptr<Trimmable> t)
|
|
|
|
{
|
2010-11-25 15:37:39 -05:00
|
|
|
boost::shared_ptr<Trimmable> st = _trimmable.lock();
|
2010-09-22 11:21:06 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!st || st == t) {
|
|
|
|
_trimmable = t;
|
|
|
|
}
|
2010-09-22 11:21:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Editor::set_current_movable (boost::shared_ptr<Movable> m)
|
|
|
|
{
|
2010-11-25 15:37:39 -05:00
|
|
|
boost::shared_ptr<Movable> sm = _movable.lock();
|
2010-09-22 11:21:06 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!sm || sm != m) {
|
|
|
|
_movable = m;
|
2010-01-01 17:11:15 -05:00
|
|
|
}
|
2008-02-16 17:43:18 -05:00
|
|
|
}
|
|
|
|
|
2012-11-26 17:43:10 -05:00
|
|
|
void
|
|
|
|
Editor::mouse_mode_object_range_toggled()
|
|
|
|
{
|
|
|
|
MouseMode m = mouse_mode;
|
|
|
|
|
|
|
|
Glib::RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range"));
|
|
|
|
assert (act);
|
|
|
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
|
|
|
assert (tact);
|
2014-02-26 08:43:53 -05:00
|
|
|
|
|
|
|
if (tact->get_active()) {
|
2012-11-26 17:43:10 -05:00
|
|
|
m = MouseObject; //Smart mode turned to ON, force editing to Object mode
|
2014-02-26 08:43:53 -05:00
|
|
|
}
|
|
|
|
|
2012-11-26 17:43:10 -05:00
|
|
|
set_mouse_mode(m, true); //call this so the button styles can get updated
|
|
|
|
}
|
|
|
|
|
2008-02-16 17:43:18 -05:00
|
|
|
void
|
2009-07-28 16:51:28 -04:00
|
|
|
Editor::set_mouse_mode (MouseMode m, bool force)
|
2008-02-16 17:43:18 -05:00
|
|
|
{
|
2010-01-12 11:14:49 -05:00
|
|
|
if (_drags->active ()) {
|
2009-07-28 16:51:28 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!force && m == mouse_mode) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-07-11 16:41:28 -04:00
|
|
|
if (ARDOUR::Profile->get_mixbus()) {
|
|
|
|
if ( m == MouseZoom) m = MouseObject;
|
|
|
|
if ( m == MouseCut) m = MouseObject;
|
|
|
|
}
|
|
|
|
|
2009-07-28 16:51:28 -04:00
|
|
|
Glib::RefPtr<Action> act;
|
|
|
|
|
|
|
|
switch (m) {
|
2008-02-16 17:43:18 -05:00
|
|
|
case MouseRange:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
|
2014-07-07 06:27:01 -04:00
|
|
|
case MouseCut:
|
2014-07-07 07:05:27 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-cut"));
|
2014-07-07 06:27:01 -04:00
|
|
|
break;
|
|
|
|
|
2008-02-16 17:43:18 -05:00
|
|
|
case MouseObject:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
case MouseDraw:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw"));
|
|
|
|
break;
|
|
|
|
|
2008-02-16 17:43:18 -05:00
|
|
|
case MouseGain:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-gain"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseZoom:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-zoom"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseTimeFX:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-timefx"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseAudition:
|
2009-07-28 16:51:28 -04:00
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-audition"));
|
2008-02-16 17:43:18 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-07-28 16:51:28 -04:00
|
|
|
assert (act);
|
|
|
|
|
|
|
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
|
|
|
assert (tact);
|
2009-08-04 14:19:40 -04:00
|
|
|
|
|
|
|
/* go there and back to ensure that the toggled handler is called to set up mouse_mode */
|
|
|
|
tact->set_active (false);
|
2009-07-28 16:51:28 -04:00
|
|
|
tact->set_active (true);
|
2010-11-21 18:54:57 -05:00
|
|
|
|
2012-11-26 17:43:10 -05:00
|
|
|
//NOTE: this will result in a call to mouse_mode_toggled which does the heavy lifting
|
2008-02-16 17:43:18 -05:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2009-07-28 16:51:28 -04:00
|
|
|
Editor::mouse_mode_toggled (MouseMode m)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2012-01-19 10:23:51 -05:00
|
|
|
Glib::RefPtr<Action> act;
|
|
|
|
Glib::RefPtr<ToggleAction> tact;
|
|
|
|
|
2014-07-11 16:41:28 -04:00
|
|
|
if (ARDOUR::Profile->get_mixbus()) {
|
|
|
|
if ( m == MouseZoom) m = MouseObject;
|
|
|
|
if ( m == MouseCut) m = MouseObject;
|
|
|
|
}
|
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
switch (m) {
|
|
|
|
case MouseRange:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseObject:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object"));
|
|
|
|
break;
|
|
|
|
|
2014-07-07 06:27:01 -04:00
|
|
|
case MouseCut:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-cut"));
|
|
|
|
break;
|
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
case MouseDraw:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseGain:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-gain"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseZoom:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-zoom"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseTimeFX:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-timefx"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseAudition:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-audition"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert (act);
|
|
|
|
|
|
|
|
tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
|
|
|
assert (tact);
|
|
|
|
|
|
|
|
if (!tact->get_active()) {
|
|
|
|
/* this was just the notification that the old mode has been
|
|
|
|
* left. we'll get called again with the new mode active in a
|
|
|
|
* jiffy.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (m) {
|
|
|
|
case MouseDraw:
|
|
|
|
act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
|
|
|
|
tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
|
|
|
tact->set_active (true);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-07-26 11:40:46 -04:00
|
|
|
|
|
|
|
if (_session && mouse_mode == MouseAudition) {
|
|
|
|
/* stop transport and reset default speed to avoid oddness with
|
|
|
|
auditioning */
|
|
|
|
_session->request_transport_speed (0.0, true);
|
|
|
|
}
|
2012-01-19 10:23:51 -05:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
mouse_mode = m;
|
|
|
|
|
|
|
|
instant_save ();
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-07 07:54:41 -04:00
|
|
|
/* this should generate a new enter event which will
|
|
|
|
trigger the appropiate cursor.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (_track_canvas) {
|
|
|
|
_track_canvas->re_enter ();
|
2010-11-25 15:37:39 -05:00
|
|
|
}
|
2014-07-07 07:54:41 -04:00
|
|
|
|
2012-05-29 14:30:10 -04:00
|
|
|
set_gain_envelope_visibility ();
|
2014-02-26 10:50:51 -05:00
|
|
|
|
|
|
|
update_time_selection_display ();
|
2010-11-21 18:54:57 -05:00
|
|
|
|
|
|
|
MouseModeChanged (); /* EMIT SIGNAL */
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2014-02-26 10:50:51 -05:00
|
|
|
void
|
|
|
|
Editor::update_time_selection_display ()
|
|
|
|
{
|
|
|
|
if (smart_mode_action->get_active()) {
|
|
|
|
/* not sure what to do here */
|
|
|
|
if (mouse_mode == MouseObject) {
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (mouse_mode) {
|
|
|
|
case MouseRange:
|
|
|
|
selection->clear_objects ();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
selection->clear_time ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
|
|
|
Editor::step_mouse_mode (bool next)
|
|
|
|
{
|
|
|
|
switch (current_mouse_mode()) {
|
|
|
|
case MouseObject:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (next) {
|
|
|
|
if (Profile->get_sae()) {
|
|
|
|
set_mouse_mode (MouseZoom);
|
|
|
|
} else {
|
|
|
|
set_mouse_mode (MouseRange);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
set_mouse_mode (MouseTimeFX);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseRange:
|
2012-01-19 10:23:51 -05:00
|
|
|
if (next) set_mouse_mode (MouseDraw);
|
2014-07-07 06:27:01 -04:00
|
|
|
else set_mouse_mode (MouseCut);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseCut:
|
|
|
|
if (next) set_mouse_mode (MouseRange);
|
|
|
|
else set_mouse_mode (MouseDraw);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
case MouseDraw:
|
2014-07-07 06:27:01 -04:00
|
|
|
if (next) set_mouse_mode (MouseCut);
|
2012-01-19 10:23:51 -05:00
|
|
|
else set_mouse_mode (MouseRange);
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseZoom:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (next) {
|
|
|
|
if (Profile->get_sae()) {
|
|
|
|
set_mouse_mode (MouseTimeFX);
|
|
|
|
} else {
|
|
|
|
set_mouse_mode (MouseGain);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (Profile->get_sae()) {
|
|
|
|
set_mouse_mode (MouseObject);
|
|
|
|
} else {
|
2012-01-19 10:23:51 -05:00
|
|
|
set_mouse_mode (MouseDraw);
|
2008-12-12 09:43:24 -05:00
|
|
|
}
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseGain:
|
|
|
|
if (next) set_mouse_mode (MouseTimeFX);
|
|
|
|
else set_mouse_mode (MouseZoom);
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseTimeFX:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (next) {
|
|
|
|
set_mouse_mode (MouseAudition);
|
|
|
|
} else {
|
|
|
|
if (Profile->get_sae()) {
|
|
|
|
set_mouse_mode (MouseZoom);
|
|
|
|
} else {
|
|
|
|
set_mouse_mode (MouseGain);
|
|
|
|
}
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseAudition:
|
|
|
|
if (next) set_mouse_mode (MouseObject);
|
|
|
|
else set_mouse_mode (MouseTimeFX);
|
|
|
|
break;
|
2007-08-10 16:55:27 -04:00
|
|
|
}
|
2007-08-08 15:13:36 -04:00
|
|
|
}
|
|
|
|
|
2012-01-24 11:20:31 -05:00
|
|
|
bool
|
|
|
|
Editor::toggle_internal_editing_from_double_click (GdkEvent* event)
|
|
|
|
{
|
|
|
|
if (_drags->active()) {
|
|
|
|
_drags->end_grab (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionManager::do_action ("MouseMode", "toggle-internal-edit");
|
|
|
|
|
|
|
|
/* prevent reversion of edit cursor on button release */
|
|
|
|
|
|
|
|
pre_press_cursor = 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
void
|
2009-07-21 11:55:17 -04:00
|
|
|
Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemType item_type)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2008-12-12 09:43:24 -05:00
|
|
|
/* 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
|
|
|
|
we want to avoid this if the mouse operation is a
|
|
|
|
region alignment.
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
note: not dbl-click or triple-click
|
2010-07-08 20:57:22 -04:00
|
|
|
|
|
|
|
Also note that there is no region selection in internal edit mode, otherwise
|
|
|
|
for operations operating on the selection (e.g. cut) it is not obvious whether
|
|
|
|
to cut notes or regions.
|
2006-06-13 03:27:52 -04:00
|
|
|
*/
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-06-30 09:17:03 -04:00
|
|
|
MouseMode eff_mouse_mode = effective_mouse_mode ();
|
2014-03-06 10:40:31 -05:00
|
|
|
|
2014-07-07 07:54:41 -04:00
|
|
|
if (eff_mouse_mode == MouseCut) {
|
|
|
|
/* never change selection in cut mode */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-06 10:40:31 -05:00
|
|
|
if (get_smart_mode() && eff_mouse_mode == MouseRange && event->button.button == 3 && item_type == RegionItem) {
|
|
|
|
/* context clicks are always about object properties, even if
|
|
|
|
we're in range mode within smart mode.
|
|
|
|
*/
|
|
|
|
eff_mouse_mode = MouseObject;
|
|
|
|
}
|
|
|
|
|
2014-06-30 09:17:03 -04:00
|
|
|
/* special case: allow drag of region fade in/out in object mode with join object/range enabled */
|
|
|
|
if (get_smart_mode()) {
|
|
|
|
switch (item_type) {
|
|
|
|
case FadeInHandleItem:
|
|
|
|
case FadeInTrimHandleItem:
|
|
|
|
case FadeOutHandleItem:
|
|
|
|
case FadeOutTrimHandleItem:
|
|
|
|
eff_mouse_mode = MouseObject;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-13 08:39:14 -04:00
|
|
|
if (((mouse_mode != MouseObject) &&
|
|
|
|
(mouse_mode != MouseAudition || item_type != RegionItem) &&
|
|
|
|
(mouse_mode != MouseTimeFX || item_type != RegionItem) &&
|
|
|
|
(mouse_mode != MouseGain) &&
|
|
|
|
(mouse_mode != MouseDraw)) ||
|
2010-07-08 20:57:22 -04:00
|
|
|
((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3) ||
|
2014-03-13 08:39:14 -04:00
|
|
|
(internal_editing() && mouse_mode != MouseTimeFX)) {
|
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
return;
|
|
|
|
}
|
2007-01-28 12:44:13 -05:00
|
|
|
|
|
|
|
if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
|
|
|
|
|
|
|
|
if ((event->button.state & Keyboard::RelevantModifierKeyMask) && event->button.button != 1) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
/* almost no selection action on modified button-2 or button-3 events */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
if (item_type != RegionItem && event->button.button != 2) {
|
|
|
|
return;
|
|
|
|
}
|
2007-01-28 12:44:13 -05:00
|
|
|
}
|
|
|
|
}
|
2008-12-12 09:43:24 -05:00
|
|
|
|
2009-12-04 17:51:32 -05:00
|
|
|
Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
|
2006-06-13 03:27:52 -04:00
|
|
|
bool press = (event->type == GDK_BUTTON_PRESS);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
2014-03-06 10:40:31 -05:00
|
|
|
if (press) {
|
|
|
|
if (eff_mouse_mode != MouseRange) {
|
|
|
|
set_selected_regionview_from_click (press, op);
|
2012-11-26 17:43:10 -05:00
|
|
|
} else {
|
2014-03-06 10:40:31 -05:00
|
|
|
/* don't change the selection unless the
|
|
|
|
clicked track is not currently selected. if
|
|
|
|
so, "collapse" the selection to just this
|
|
|
|
track
|
|
|
|
*/
|
|
|
|
if (!selection->selected (clicked_axisview)) {
|
|
|
|
set_selected_track_as_side_effect (Selection::Set);
|
2012-01-30 17:53:22 -05:00
|
|
|
}
|
|
|
|
}
|
2014-03-06 10:40:31 -05:00
|
|
|
} else {
|
|
|
|
if (eff_mouse_mode != MouseRange) {
|
|
|
|
set_selected_regionview_from_click (press, op);
|
|
|
|
}
|
2007-10-11 18:07:47 -04:00
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-10-11 18:07:47 -04:00
|
|
|
case RegionViewNameHighlight:
|
|
|
|
case RegionViewName:
|
2010-11-25 15:37:39 -05:00
|
|
|
case LeftFrameHandle:
|
|
|
|
case RightFrameHandle:
|
2007-01-28 12:44:13 -05:00
|
|
|
case FadeInHandleItem:
|
2014-05-30 21:53:59 -04:00
|
|
|
case FadeInTrimHandleItem:
|
2007-01-28 12:44:13 -05:00
|
|
|
case FadeInItem:
|
|
|
|
case FadeOutHandleItem:
|
2014-05-30 21:53:59 -04:00
|
|
|
case FadeOutTrimHandleItem:
|
2007-01-28 12:44:13 -05:00
|
|
|
case FadeOutItem:
|
2012-05-11 17:30:36 -04:00
|
|
|
case StartCrossFadeItem:
|
|
|
|
case EndCrossFadeItem:
|
2014-06-30 19:18:27 -04:00
|
|
|
if (get_smart_mode() || eff_mouse_mode != MouseRange) {
|
2012-01-30 17:53:22 -05:00
|
|
|
set_selected_regionview_from_click (press, op);
|
2007-03-18 02:07:08 -04:00
|
|
|
} else if (event->type == GDK_BUTTON_PRESS) {
|
2010-08-26 19:25:44 -04:00
|
|
|
set_selected_track_as_side_effect (op);
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
2006-06-13 03:27:52 -04:00
|
|
|
break;
|
2007-05-10 07:53:35 -04:00
|
|
|
|
2007-06-30 14:41:50 -04:00
|
|
|
case ControlPointItem:
|
2012-01-30 17:53:22 -05:00
|
|
|
set_selected_track_as_side_effect (op);
|
2014-03-13 08:39:14 -04:00
|
|
|
if (eff_mouse_mode != MouseRange) {
|
2012-04-22 19:14:27 -04:00
|
|
|
set_selected_control_point_from_click (press, op);
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
2006-06-13 03:27:52 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
case StreamItem:
|
2009-12-13 16:27:19 -05:00
|
|
|
/* for context click, select track */
|
2007-03-18 02:07:08 -04:00
|
|
|
if (event->button.button == 3) {
|
2010-04-22 22:06:07 -04:00
|
|
|
selection->clear_tracks ();
|
2012-01-30 17:53:22 -05:00
|
|
|
set_selected_track_as_side_effect (op);
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
2006-06-13 03:27:52 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
case AutomationTrackItem:
|
2012-01-30 17:53:22 -05:00
|
|
|
set_selected_track_as_side_effect (op);
|
2006-06-13 03:27:52 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
default:
|
|
|
|
break;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-06-13 03:27:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2009-08-04 14:21:09 -04:00
|
|
|
Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
2006-06-13 03:27:52 -04:00
|
|
|
{
|
2009-08-04 14:21:09 -04:00
|
|
|
/* single mouse clicks on any of these item types operate
|
|
|
|
independent of mouse mode, mostly because they are
|
|
|
|
not on the main track canvas or because we want
|
|
|
|
them to be modeless.
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
switch (item_type) {
|
|
|
|
case PlayheadCursorItem:
|
2013-04-17 15:22:09 -04:00
|
|
|
_drags->set (new CursorDrag (this, *playhead_cursor, true), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case MarkerItem:
|
|
|
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
|
|
|
hide_marker (item, event);
|
2008-09-10 11:03:30 -04:00
|
|
|
} else {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new MarkerDrag (this, item), event);
|
2008-09-10 11:03:30 -04:00
|
|
|
}
|
2006-06-13 03:27:52 -04:00
|
|
|
return true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case TempoMarkerItem:
|
2011-09-08 13:49:36 -04:00
|
|
|
{
|
|
|
|
TempoMarker* m = reinterpret_cast<TempoMarker*> (item->get_data ("marker"));
|
|
|
|
assert (m);
|
2014-01-27 10:09:58 -05:00
|
|
|
_drags->set (
|
|
|
|
new TempoMarkerDrag (
|
|
|
|
this,
|
|
|
|
item,
|
|
|
|
Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
|
|
|
|
),
|
|
|
|
event
|
|
|
|
);
|
|
|
|
return true;
|
2011-09-08 13:49:36 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case MeterMarkerItem:
|
2011-09-08 13:49:36 -04:00
|
|
|
{
|
|
|
|
MeterMarker* m = reinterpret_cast<MeterMarker*> (item->get_data ("marker"));
|
|
|
|
assert (m);
|
2014-01-27 10:09:58 -05:00
|
|
|
_drags->set (
|
|
|
|
new MeterMarkerDrag (
|
|
|
|
this,
|
|
|
|
item,
|
|
|
|
Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
|
|
|
|
),
|
|
|
|
event
|
|
|
|
);
|
|
|
|
return true;
|
2011-09-08 13:49:36 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2013-03-12 17:00:09 -04:00
|
|
|
case VideoBarItem:
|
|
|
|
_drags->set (new VideoTimeLineDrag (this, item), event);
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case MarkerBarItem:
|
|
|
|
case TempoBarItem:
|
|
|
|
case MeterBarItem:
|
2014-06-12 16:06:31 -04:00
|
|
|
case TimecodeRulerItem:
|
|
|
|
case SamplesRulerItem:
|
|
|
|
case MinsecRulerItem:
|
|
|
|
case BBTRulerItem:
|
2009-08-04 14:21:09 -04:00
|
|
|
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
2013-04-17 15:22:09 -04:00
|
|
|
_drags->set (new CursorDrag (this, *playhead_cursor, false), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
break;
|
2008-12-12 09:43:24 -05:00
|
|
|
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case RangeMarkerBarItem:
|
2014-09-17 10:59:19 -04:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
|
|
|
|
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateSkipMarker), event);
|
|
|
|
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker), event);
|
2014-09-17 10:59:19 -04:00
|
|
|
} else {
|
|
|
|
_drags->set (new CursorDrag (this, *playhead_cursor, false), event);
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case CdMarkerBarItem:
|
|
|
|
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
2013-04-17 15:22:09 -04:00
|
|
|
_drags->set (new CursorDrag (this, *playhead_cursor, false), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
} else {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case TransportMarkerBarItem:
|
|
|
|
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
2013-04-17 15:22:09 -04:00
|
|
|
_drags->set (new CursorDrag (this, *playhead_cursor, false), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
} else {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
default:
|
|
|
|
break;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-01 20:19:47 -05:00
|
|
|
if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
|
|
|
|
/* special case: allow trim of range selections in joined object mode;
|
|
|
|
in theory eff should equal MouseRange in this case, but it doesn't
|
|
|
|
because entering the range selection canvas item results in entered_regionview
|
|
|
|
being set to 0, so update_join_object_range_location acts as if we aren't
|
|
|
|
over a region.
|
|
|
|
*/
|
2010-01-01 20:36:19 -05:00
|
|
|
if (item_type == StartSelectionTrimItem) {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim), event);
|
2010-01-01 20:36:19 -05:00
|
|
|
} else if (item_type == EndSelectionTrimItem) {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim), event);
|
2010-01-01 20:19:47 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-01 17:11:15 -05:00
|
|
|
Editing::MouseMode eff = effective_mouse_mode ();
|
|
|
|
|
2010-01-24 21:24:44 -05:00
|
|
|
/* special case: allow drag of region fade in/out in object mode with join object/range enabled */
|
2014-06-30 09:17:03 -04:00
|
|
|
if (get_smart_mode()) {
|
|
|
|
switch (item_type) {
|
|
|
|
case FadeInHandleItem:
|
|
|
|
case FadeInTrimHandleItem:
|
|
|
|
case FadeOutHandleItem:
|
|
|
|
case FadeOutTrimHandleItem:
|
|
|
|
eff = MouseObject;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2010-01-24 21:24:44 -05:00
|
|
|
}
|
|
|
|
|
2013-01-24 16:56:03 -05:00
|
|
|
/* there is no Range mode when in internal edit mode */
|
|
|
|
if (eff == MouseRange && internal_editing()) {
|
|
|
|
eff = MouseObject;
|
|
|
|
}
|
|
|
|
|
2010-01-01 17:11:15 -05:00
|
|
|
switch (eff) {
|
2009-11-18 08:24:43 -05:00
|
|
|
case MouseRange:
|
2009-08-28 12:06:08 -04:00
|
|
|
switch (item_type) {
|
2009-11-18 08:24:43 -05:00
|
|
|
case StartSelectionTrimItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EndSelectionTrimItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SelectionItem:
|
2012-12-13 14:39:36 -05:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
2009-11-18 08:24:43 -05:00
|
|
|
start_selection_grab (item, event);
|
2013-04-04 00:32:52 -04:00
|
|
|
return true;
|
2010-03-16 16:16:13 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::SecondaryModifier)) {
|
2009-11-18 08:24:43 -05:00
|
|
|
/* grab selection for moving */
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
} else {
|
2014-08-05 16:42:06 -04:00
|
|
|
/* this was debated, but decided the more common action was to
|
|
|
|
make a new selection */
|
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
2009-09-08 17:45:44 -04:00
|
|
|
}
|
|
|
|
break;
|
2009-11-18 08:24:43 -05:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
case StreamItem:
|
|
|
|
if (internal_editing()) {
|
2010-08-20 08:01:13 -04:00
|
|
|
if (dynamic_cast<MidiTimeAxisView*> (clicked_axisview)) {
|
|
|
|
_drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
|
|
|
|
return true;
|
2011-07-13 08:34:11 -04:00
|
|
|
}
|
2010-11-25 15:37:39 -05:00
|
|
|
} else {
|
2012-12-13 14:39:36 -05:00
|
|
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::RangeSelectModifier)) {
|
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionExtend), event);
|
|
|
|
} else {
|
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
|
|
|
}
|
2010-06-21 21:28:49 -04:00
|
|
|
return true;
|
|
|
|
}
|
2010-11-25 15:37:39 -05:00
|
|
|
break;
|
2010-05-29 07:28:27 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
case RegionViewNameHighlight:
|
2011-02-09 09:02:49 -05:00
|
|
|
if (!clicked_regionview->region()->locked()) {
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
|
2010-11-25 15:37:39 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2010-05-30 16:13:29 -04:00
|
|
|
|
2009-08-28 12:06:08 -04:00
|
|
|
default:
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!internal_editing()) {
|
2012-12-13 14:39:36 -05:00
|
|
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::RangeSelectModifier)) {
|
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionExtend), event);
|
|
|
|
} else {
|
|
|
|
_drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
|
|
|
|
}
|
2010-11-25 15:37:39 -05:00
|
|
|
}
|
2009-08-28 12:06:08 -04:00
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-02-08 07:50:32 -05:00
|
|
|
case MouseDraw:
|
|
|
|
switch (item_type) {
|
|
|
|
case NoteItem:
|
2014-03-07 11:22:49 -05:00
|
|
|
/* Existing note: allow trimming/motion */
|
2012-02-08 07:50:32 -05:00
|
|
|
if (internal_editing()) {
|
|
|
|
/* trim notes if we're in internal edit mode and near the ends of the note */
|
2013-04-04 18:45:27 -04:00
|
|
|
NoteBase* cn = reinterpret_cast<NoteBase*>(item->get_data ("notebase"));
|
2013-04-04 00:32:52 -04:00
|
|
|
assert (cn);
|
2014-03-07 11:22:49 -05:00
|
|
|
if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
|
2012-02-08 07:50:32 -05:00
|
|
|
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
|
|
|
} else {
|
|
|
|
_drags->set (new NoteDrag (this, item), event);
|
|
|
|
}
|
|
|
|
return true;
|
2014-03-07 11:22:49 -05:00
|
|
|
}
|
2012-02-08 07:50:32 -05:00
|
|
|
break;
|
2013-01-20 14:16:58 -05:00
|
|
|
case StreamItem:
|
|
|
|
if (internal_editing()) {
|
|
|
|
if (dynamic_cast<MidiTimeAxisView*> (clicked_axisview)) {
|
|
|
|
_drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2012-02-08 07:50:32 -05:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-04-06 21:57:11 -04:00
|
|
|
break;
|
2012-02-08 07:50:32 -05:00
|
|
|
|
2014-07-07 07:05:27 -04:00
|
|
|
case MouseCut:
|
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
|
|
|
case FadeInHandleItem:
|
|
|
|
case FadeOutHandleItem:
|
|
|
|
case LeftFrameHandle:
|
|
|
|
case RightFrameHandle:
|
|
|
|
case FeatureLineItem:
|
|
|
|
case RegionViewNameHighlight:
|
|
|
|
case RegionViewName:
|
2014-07-08 20:28:27 -04:00
|
|
|
case StreamItem:
|
2014-07-08 21:36:05 -04:00
|
|
|
case AutomationTrackItem:
|
2014-07-07 10:13:19 -04:00
|
|
|
_drags->set (new RegionCutDrag (this, item, canvas_event_sample (event)), event, current_canvas_cursor);
|
2014-07-07 07:54:41 -04:00
|
|
|
return true;
|
2014-07-07 07:05:27 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case MouseObject:
|
|
|
|
switch (item_type) {
|
|
|
|
case NoteItem:
|
2014-03-07 11:22:49 -05:00
|
|
|
/* Existing note: allow trimming/motion */
|
2009-11-18 08:24:43 -05:00
|
|
|
if (internal_editing()) {
|
2013-04-04 00:32:52 -04:00
|
|
|
NoteBase* cn = reinterpret_cast<NoteBase*> (item->get_data ("notebase"));
|
|
|
|
assert (cn);
|
2014-03-07 11:22:49 -05:00
|
|
|
if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
|
2010-11-25 15:37:39 -05:00
|
|
|
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
|
|
|
} else {
|
|
|
|
_drags->set (new NoteDrag (this, item), event);
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
|
|
|
|
event->type == GDK_BUTTON_PRESS) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2011-11-16 15:11:33 -05:00
|
|
|
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
|
|
|
|
} else if (event->type == GDK_BUTTON_PRESS) {
|
|
|
|
|
|
|
|
switch (item_type) {
|
|
|
|
case FadeInHandleItem:
|
|
|
|
{
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->set (new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), selection->regions), event, _cursors->fade_in);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case FadeOutHandleItem:
|
|
|
|
{
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->set (new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), selection->regions), event, _cursors->fade_out);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-05-09 19:04:18 -04:00
|
|
|
case StartCrossFadeItem:
|
|
|
|
case EndCrossFadeItem:
|
2012-12-13 11:42:05 -05:00
|
|
|
/* we might allow user to grab inside the fade to trim a region with preserve_fade_anchor. for not this is not fully implemented */
|
|
|
|
// if (!clicked_regionview->region()->locked()) {
|
2013-06-10 12:51:59 -04:00
|
|
|
// _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer(), true), event);
|
2012-12-13 11:42:05 -05:00
|
|
|
// return true;
|
|
|
|
// }
|
2012-05-09 19:04:18 -04:00
|
|
|
break;
|
|
|
|
|
2010-07-06 07:33:27 -04:00
|
|
|
case FeatureLineItem:
|
2011-06-01 13:00:29 -04:00
|
|
|
{
|
2010-07-06 07:33:27 -04:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
|
|
|
|
remove_transient(item);
|
|
|
|
return true;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-07-06 07:33:27 -04:00
|
|
|
_drags->set (new FeatureLineDrag (this, item), event);
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case RegionItem:
|
2010-08-04 11:41:55 -04:00
|
|
|
if (dynamic_cast<AutomationRegionView*> (clicked_regionview)) {
|
|
|
|
/* click on an automation region view; do nothing here and let the ARV's signal handler
|
|
|
|
sort it out.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
2010-09-18 16:22:03 -04:00
|
|
|
|
|
|
|
if (internal_editing ()) {
|
|
|
|
break;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-08-04 11:41:55 -04:00
|
|
|
/* click on a normal region view */
|
2009-11-18 08:24:43 -05:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
|
2010-01-12 11:14:49 -05:00
|
|
|
add_region_copy_drag (item, event, clicked_regionview);
|
2011-03-02 12:00:54 -05:00
|
|
|
} else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
|
2010-01-12 11:14:49 -05:00
|
|
|
add_region_brush_drag (item, event, clicked_regionview);
|
2009-11-18 08:24:43 -05:00
|
|
|
} else {
|
2010-01-12 11:14:49 -05:00
|
|
|
add_region_drag (item, event, clicked_regionview);
|
2009-11-18 08:24:43 -05:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2012-01-30 17:53:22 -05:00
|
|
|
|
2012-11-26 17:43:10 -05:00
|
|
|
// if (!internal_editing() && (_join_object_range_state == JOIN_OBJECT_RANGE_RANGE && !selection->regions.empty())) {
|
|
|
|
// _drags->add (new SelectionDrag (this, clicked_axisview->get_selection_rect (clicked_selection)->rect, SelectionDrag::SelectionMove));
|
|
|
|
// }
|
2010-01-12 11:14:49 -05:00
|
|
|
|
|
|
|
_drags->start_grab (event);
|
2013-04-04 00:32:52 -04:00
|
|
|
return true;
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case RegionViewNameHighlight:
|
2010-06-17 08:45:51 -04:00
|
|
|
case LeftFrameHandle:
|
2014-05-30 21:53:59 -04:00
|
|
|
case RightFrameHandle:
|
2011-02-09 09:02:49 -05:00
|
|
|
if (!clicked_regionview->region()->locked()) {
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
|
2010-07-21 22:12:28 -04:00
|
|
|
return true;
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-05-30 21:53:59 -04:00
|
|
|
case FadeInTrimHandleItem:
|
|
|
|
case FadeOutTrimHandleItem:
|
|
|
|
if (!clicked_regionview->region()->locked()) {
|
|
|
|
_drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer(), true), event);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case RegionViewName:
|
|
|
|
{
|
|
|
|
/* rename happens on edit clicks */
|
2014-06-08 11:23:00 -04:00
|
|
|
if (clicked_regionview->get_name_highlight()) {
|
|
|
|
_drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event);
|
|
|
|
return true;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case ControlPointItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new ControlPointDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case AutomationLineItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new LineDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case StreamItem:
|
|
|
|
if (internal_editing()) {
|
2010-08-20 08:01:13 -04:00
|
|
|
if (dynamic_cast<MidiTimeAxisView*> (clicked_axisview)) {
|
|
|
|
_drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2010-01-01 17:11:15 -05:00
|
|
|
} else {
|
2011-11-16 15:11:33 -05:00
|
|
|
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
}
|
2010-01-01 17:11:15 -05:00
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case AutomationTrackItem:
|
2011-07-13 08:34:11 -04:00
|
|
|
{
|
|
|
|
TimeAxisView* parent = clicked_axisview->get_parent ();
|
2011-09-07 09:45:52 -04:00
|
|
|
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (clicked_axisview);
|
|
|
|
assert (atv);
|
|
|
|
if (parent && dynamic_cast<MidiTimeAxisView*> (parent) && atv->show_regions ()) {
|
2012-06-08 20:36:21 -04:00
|
|
|
|
|
|
|
RouteTimeAxisView* p = dynamic_cast<RouteTimeAxisView*> (parent);
|
|
|
|
assert (p);
|
|
|
|
boost::shared_ptr<Playlist> pl = p->track()->playlist ();
|
|
|
|
if (pl->n_regions() == 0) {
|
|
|
|
/* Parent has no regions; create one so that we have somewhere to put automation */
|
|
|
|
_drags->set (new RegionCreateDrag (this, item, parent), event);
|
|
|
|
} else {
|
|
|
|
/* See if there's a region before the click that we can extend, and extend it if so */
|
2014-02-26 08:43:53 -05:00
|
|
|
framepos_t const t = canvas_event_sample (event);
|
2012-06-08 20:36:21 -04:00
|
|
|
boost::shared_ptr<Region> prev = pl->find_next_region (t, End, -1);
|
|
|
|
if (!prev) {
|
|
|
|
_drags->set (new RegionCreateDrag (this, item, parent), event);
|
|
|
|
} else {
|
|
|
|
prev->set_length (t - prev->position ());
|
|
|
|
}
|
|
|
|
}
|
2011-07-13 08:34:11 -04:00
|
|
|
} else {
|
|
|
|
/* rubberband drag to select automation points */
|
2011-11-16 15:11:33 -05:00
|
|
|
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
2011-07-13 08:34:11 -04:00
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
break;
|
2011-07-13 08:34:11 -04:00
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
|
2010-01-01 17:11:15 -05:00
|
|
|
case SelectionItem:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case MarkerBarItem:
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseGain:
|
|
|
|
switch (item_type) {
|
|
|
|
case GainLineItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new LineDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case ControlPointItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new ControlPointDrag (this, item), event);
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-03-22 12:41:23 -04:00
|
|
|
case SelectionItem:
|
|
|
|
{
|
|
|
|
AudioRegionView* arv = dynamic_cast<AudioRegionView *> (clicked_regionview);
|
|
|
|
if (arv) {
|
|
|
|
_drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down);
|
2014-08-05 16:42:06 -04:00
|
|
|
} else {
|
|
|
|
double const y = event->button.y;
|
|
|
|
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
|
|
|
|
if (tvp.first) {
|
|
|
|
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
|
|
|
if ( atv) {
|
|
|
|
/* smart "join" mode: drag automation */
|
|
|
|
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
|
|
|
|
}
|
|
|
|
}
|
2012-03-22 12:41:23 -04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-18 08:24:43 -05:00
|
|
|
case AutomationLineItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new LineDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
break;
|
2012-03-09 15:47:40 -05:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseZoom:
|
|
|
|
if (event->type == GDK_BUTTON_PRESS) {
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new MouseZoomDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseTimeFX:
|
2014-03-07 11:22:49 -05:00
|
|
|
if (internal_editing() && item_type == NoteItem ) {
|
2010-04-28 19:16:07 -04:00
|
|
|
/* drag notes if we're in internal edit mode */
|
2014-03-07 11:22:49 -05:00
|
|
|
NoteBase* cn = reinterpret_cast<NoteBase*>(item->get_data ("notebase"));
|
|
|
|
assert (cn);
|
|
|
|
if (cn->big_enough_to_trim()) {
|
|
|
|
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
|
|
|
|
}
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
2012-05-29 16:29:47 -04:00
|
|
|
} else if (clicked_regionview) {
|
|
|
|
/* do time-FX */
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseAudition:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new ScrubDrag (this, item), event);
|
2009-11-18 08:24:43 -05:00
|
|
|
scrub_reversals = 0;
|
|
|
|
scrub_reverse_distance = 0;
|
|
|
|
last_scrub_x = event->button.x;
|
|
|
|
scrubbing_direction = 0;
|
2014-06-18 10:24:59 -04:00
|
|
|
push_canvas_cursor (_cursors->transparent);
|
2009-11-18 08:24:43 -05:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
|
|
|
{
|
2010-01-01 17:11:15 -05:00
|
|
|
Editing::MouseMode const eff = effective_mouse_mode ();
|
|
|
|
switch (eff) {
|
2009-08-04 14:21:09 -04:00
|
|
|
case MouseObject:
|
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
2011-03-24 07:48:12 -04:00
|
|
|
if (internal_editing ()) {
|
|
|
|
/* no region drags in internal edit mode */
|
|
|
|
return false;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
|
2010-01-12 11:14:49 -05:00
|
|
|
add_region_copy_drag (item, event, clicked_regionview);
|
2005-09-25 14:42:24 -04:00
|
|
|
} else {
|
2010-01-12 11:14:49 -05:00
|
|
|
add_region_drag (item, event, clicked_regionview);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->start_grab (event);
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-08-04 14:21:09 -04:00
|
|
|
case ControlPointItem:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new ControlPointDrag (this, item), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
switch (item_type) {
|
|
|
|
case RegionViewNameHighlight:
|
2014-05-30 21:53:59 -04:00
|
|
|
_drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
|
|
|
|
return true;
|
|
|
|
break;
|
2011-02-09 09:02:49 -05:00
|
|
|
|
2014-05-30 21:53:59 -04:00
|
|
|
case LeftFrameHandle:
|
|
|
|
case RightFrameHandle:
|
2010-07-21 22:12:28 -04:00
|
|
|
if (!internal_editing ()) {
|
|
|
|
_drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
|
|
|
|
}
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case RegionViewName:
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event);
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
break;
|
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
case MouseDraw:
|
|
|
|
return false;
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case MouseRange:
|
|
|
|
/* relax till release */
|
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
case MouseZoom:
|
|
|
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
2014-02-26 08:43:53 -05:00
|
|
|
temporal_zoom_to_frame (false, canvas_event_sample (event));
|
2009-08-04 14:21:09 -04:00
|
|
|
} else {
|
2014-02-26 08:43:53 -05:00
|
|
|
temporal_zoom_to_frame (true, canvas_event_sample(event));
|
2009-08-04 14:21:09 -04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
return false;
|
|
|
|
}
|
2012-01-24 11:20:31 -05:00
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
bool
|
|
|
|
Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
|
|
|
{
|
2013-06-21 15:18:54 -04:00
|
|
|
if (event->type == GDK_2BUTTON_PRESS) {
|
|
|
|
_drags->mark_double_click ();
|
2014-01-27 10:09:58 -05:00
|
|
|
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
|
|
|
return true;
|
2013-06-21 15:18:54 -04:00
|
|
|
}
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
if (event->type != GDK_BUTTON_PRESS) {
|
|
|
|
return false;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-09-22 11:21:06 -04:00
|
|
|
pre_press_cursor = current_canvas_cursor;
|
2014-03-11 22:38:48 -04:00
|
|
|
|
2013-04-04 00:32:52 -04:00
|
|
|
_track_canvas->grab_focus();
|
2009-08-04 14:21:09 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
if (_session && _session->actively_recording()) {
|
2009-08-04 14:21:09 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-01-24 11:20:31 -05:00
|
|
|
if (internal_editing()) {
|
2012-01-24 17:17:24 -05:00
|
|
|
bool leave_internal_edit_mode = false;
|
|
|
|
|
2012-01-24 11:20:31 -05:00
|
|
|
switch (item_type) {
|
|
|
|
case NoteItem:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RegionItem:
|
2012-03-22 12:41:23 -04:00
|
|
|
if (!dynamic_cast<MidiRegionView*> (clicked_regionview) && !dynamic_cast<AutomationRegionView*> (clicked_regionview)) {
|
2012-01-24 17:17:24 -05:00
|
|
|
leave_internal_edit_mode = true;
|
2012-01-24 11:20:31 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PlayheadCursorItem:
|
|
|
|
case MarkerItem:
|
|
|
|
case TempoMarkerItem:
|
|
|
|
case MeterMarkerItem:
|
|
|
|
case MarkerBarItem:
|
|
|
|
case TempoBarItem:
|
|
|
|
case MeterBarItem:
|
|
|
|
case RangeMarkerBarItem:
|
|
|
|
case CdMarkerBarItem:
|
|
|
|
case TransportMarkerBarItem:
|
2013-01-20 14:16:58 -05:00
|
|
|
case StreamItem:
|
2014-06-12 16:06:31 -04:00
|
|
|
case TimecodeRulerItem:
|
|
|
|
case SamplesRulerItem:
|
|
|
|
case MinsecRulerItem:
|
|
|
|
case BBTRulerItem:
|
|
|
|
/* button press on these items never does anything to
|
2012-01-24 11:20:31 -05:00
|
|
|
change the editing mode.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-01-24 17:17:24 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (leave_internal_edit_mode) {
|
2012-01-24 11:20:31 -05:00
|
|
|
ActionManager::do_action ("MouseMode", "toggle-internal-edit");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-10 12:41:51 -04:00
|
|
|
button_selection (item, event, item_type);
|
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (!_drags->active () &&
|
2009-08-04 14:21:09 -04:00
|
|
|
(Keyboard::is_delete_event (&event->button) ||
|
|
|
|
Keyboard::is_context_menu_event (&event->button) ||
|
|
|
|
Keyboard::is_edit_event (&event->button))) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
/* handled by button release */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-11-20 14:43:43 -05:00
|
|
|
//not rolling, range mode click + join_play_range : locate the PH here
|
2014-07-03 13:25:35 -04:00
|
|
|
if ( !_drags->active () && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && Config->get_follow_edits() ) {
|
2014-02-26 08:43:53 -05:00
|
|
|
framepos_t where = canvas_event_sample (event);
|
2012-11-20 14:43:43 -05:00
|
|
|
snap_to(where);
|
|
|
|
_session->request_locate (where, false);
|
|
|
|
}
|
|
|
|
|
2009-08-04 14:21:09 -04:00
|
|
|
switch (event->button.button) {
|
|
|
|
case 1:
|
|
|
|
return button_press_handler_1 (item, event, item_type);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
return button_press_handler_2 (item, event, item_type);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2011-03-03 22:10:48 -05:00
|
|
|
return button_press_dispatch (&event->button);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
|
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-03-03 22:10:48 -05:00
|
|
|
bool
|
|
|
|
Editor::button_press_dispatch (GdkEventButton* ev)
|
|
|
|
{
|
|
|
|
/* this function is intended only for buttons 4 and above.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Gtkmm2ext::MouseButton b (ev->state, ev->button);
|
|
|
|
return button_bindings->activate (b, Gtkmm2ext::Bindings::Press);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Editor::button_release_dispatch (GdkEventButton* ev)
|
|
|
|
{
|
|
|
|
/* this function is intended only for buttons 4 and above.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Gtkmm2ext::MouseButton b (ev->state, ev->button);
|
|
|
|
return button_bindings->activate (b, Gtkmm2ext::Bindings::Release);
|
|
|
|
}
|
|
|
|
|
2005-11-22 00:10:12 -05:00
|
|
|
bool
|
2005-11-23 12:21:12 -05:00
|
|
|
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2014-02-26 08:43:53 -05:00
|
|
|
framepos_t where = canvas_event_sample (event);
|
2009-07-09 13:58:13 -04:00
|
|
|
AutomationTimeAxisView* atv = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-09-22 11:21:06 -04:00
|
|
|
if (pre_press_cursor) {
|
|
|
|
set_canvas_cursor (pre_press_cursor);
|
|
|
|
pre_press_cursor = 0;
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
/* no action if we're recording */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
if (_session && _session->actively_recording()) {
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2010-08-09 21:52:49 -04:00
|
|
|
/* see if we're finishing a drag */
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-06-01 20:39:57 -04:00
|
|
|
bool were_dragging = false;
|
2010-01-12 11:14:49 -05:00
|
|
|
if (_drags->active ()) {
|
|
|
|
bool const r = _drags->end_grab (event);
|
2009-05-30 14:25:59 -04:00
|
|
|
if (r) {
|
2005-09-25 14:42:24 -04:00
|
|
|
/* grab dragged, so do nothing else */
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-06-01 20:39:57 -04:00
|
|
|
|
|
|
|
were_dragging = true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2013-07-10 19:10:06 -04:00
|
|
|
update_region_layering_order_editor ();
|
2010-08-25 15:28:33 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
/* edit events get handled here */
|
2008-12-12 09:43:24 -05:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (!_drags->active () && Keyboard::is_edit_event (&event->button)) {
|
2005-09-25 14:42:24 -04:00
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
2010-11-03 18:19:29 -04:00
|
|
|
show_region_properties ();
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
2014-01-27 10:09:58 -05:00
|
|
|
case TempoMarkerItem: {
|
|
|
|
Marker* marker;
|
|
|
|
TempoMarker* tempo_marker;
|
|
|
|
|
|
|
|
if ((marker = reinterpret_cast<Marker *> (item->get_data ("marker"))) == 0) {
|
|
|
|
fatal << _("programming error: tempo marker canvas item has no marker object pointer!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tempo_marker = dynamic_cast<TempoMarker*> (marker)) == 0) {
|
|
|
|
fatal << _("programming error: marker for tempo is not a tempo marker!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
|
|
|
|
edit_tempo_marker (*tempo_marker);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2014-01-27 10:09:58 -05:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-01-27 10:09:58 -05:00
|
|
|
case MeterMarkerItem: {
|
|
|
|
Marker* marker;
|
|
|
|
MeterMarker* meter_marker;
|
|
|
|
|
|
|
|
if ((marker = reinterpret_cast<Marker *> (item->get_data ("marker"))) == 0) {
|
|
|
|
fatal << _("programming error: tempo marker canvas item has no marker object pointer!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((meter_marker = dynamic_cast<MeterMarker*> (marker)) == 0) {
|
|
|
|
fatal << _("programming error: marker for meter is not a meter marker!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
edit_meter_marker (*meter_marker);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2014-01-27 10:09:58 -05:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-07-23 08:03:19 -04:00
|
|
|
case RegionViewName:
|
2005-09-25 14:42:24 -04:00
|
|
|
if (clicked_regionview->name_active()) {
|
|
|
|
return mouse_rename_region (item, event);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2008-12-18 12:46:28 -05:00
|
|
|
case ControlPointItem:
|
|
|
|
edit_control_point (item);
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* context menu events get handled here */
|
|
|
|
if (Keyboard::is_context_menu_event (&event->button)) {
|
|
|
|
|
2011-12-26 18:18:24 -05:00
|
|
|
context_click_event = *event;
|
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (!_drags->active ()) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
/* no matter which button pops up the context menu, tell the menu
|
|
|
|
widget to use button 1 to drive menu selection.
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch (item_type) {
|
|
|
|
case FadeInItem:
|
|
|
|
case FadeInHandleItem:
|
2014-05-30 21:53:59 -04:00
|
|
|
case FadeInTrimHandleItem:
|
2012-05-10 15:14:11 -04:00
|
|
|
case StartCrossFadeItem:
|
2014-06-30 13:58:39 -04:00
|
|
|
case LeftFrameHandle:
|
2012-05-11 17:30:36 -04:00
|
|
|
popup_xfade_in_context_menu (1, event->button.time, item, item_type);
|
2012-05-10 15:14:11 -04:00
|
|
|
break;
|
|
|
|
|
2014-05-29 01:49:26 -04:00
|
|
|
case FadeOutItem:
|
|
|
|
case FadeOutHandleItem:
|
2014-05-30 21:53:59 -04:00
|
|
|
case FadeOutTrimHandleItem:
|
2012-05-10 15:14:11 -04:00
|
|
|
case EndCrossFadeItem:
|
2014-06-30 13:58:39 -04:00
|
|
|
case RightFrameHandle:
|
2012-05-11 17:30:36 -04:00
|
|
|
popup_xfade_out_context_menu (1, event->button.time, item, item_type);
|
2012-05-10 15:14:11 -04:00
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case StreamItem:
|
2010-11-14 11:49:59 -05:00
|
|
|
popup_track_context_menu (1, event->button.time, item_type, false);
|
2007-10-11 18:07:47 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case RegionItem:
|
2006-07-23 08:03:19 -04:00
|
|
|
case RegionViewNameHighlight:
|
|
|
|
case RegionViewName:
|
2010-11-14 11:49:59 -05:00
|
|
|
popup_track_context_menu (1, event->button.time, item_type, false);
|
2007-10-11 18:07:47 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case SelectionItem:
|
2010-11-14 11:49:59 -05:00
|
|
|
popup_track_context_menu (1, event->button.time, item_type, true);
|
2007-10-11 18:07:47 -04:00
|
|
|
break;
|
2012-05-10 15:14:11 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case AutomationTrackItem:
|
2010-11-14 11:49:59 -05:00
|
|
|
popup_track_context_menu (1, event->button.time, item_type, false);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
2009-10-14 12:10:01 -04:00
|
|
|
case MarkerBarItem:
|
|
|
|
case RangeMarkerBarItem:
|
2008-01-10 16:20:59 -05:00
|
|
|
case TransportMarkerBarItem:
|
|
|
|
case CdMarkerBarItem:
|
2005-09-25 14:42:24 -04:00
|
|
|
case TempoBarItem:
|
|
|
|
case MeterBarItem:
|
2013-03-12 17:00:09 -04:00
|
|
|
case VideoBarItem:
|
2014-06-12 16:06:31 -04:00
|
|
|
case TimecodeRulerItem:
|
|
|
|
case SamplesRulerItem:
|
|
|
|
case MinsecRulerItem:
|
|
|
|
case BBTRulerItem:
|
2009-03-21 09:08:06 -04:00
|
|
|
popup_ruler_menu (where, item_type);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MarkerItem:
|
|
|
|
marker_context_menu (&event->button, item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TempoMarkerItem:
|
2010-05-02 19:14:43 -04:00
|
|
|
tempo_or_meter_marker_context_menu (&event->button, item);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MeterMarkerItem:
|
2010-05-02 19:14:43 -04:00
|
|
|
tempo_or_meter_marker_context_menu (&event->button, item);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-01-12 18:45:50 -05:00
|
|
|
case CrossfadeViewItem:
|
2010-11-14 11:49:59 -05:00
|
|
|
popup_track_context_menu (1, event->button.time, item_type, false);
|
2008-01-12 18:45:50 -05:00
|
|
|
break;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2011-07-17 16:10:31 -04:00
|
|
|
case ControlPointItem:
|
|
|
|
popup_control_point_context_menu (item, event);
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* delete events get handled here */
|
|
|
|
|
2010-01-01 17:11:15 -05:00
|
|
|
Editing::MouseMode const eff = effective_mouse_mode ();
|
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (!_drags->active () && Keyboard::is_delete_event (&event->button)) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
switch (item_type) {
|
|
|
|
case TempoMarkerItem:
|
|
|
|
remove_tempo_marker (item);
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MeterMarkerItem:
|
|
|
|
remove_meter_marker (item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MarkerItem:
|
2005-11-12 22:53:51 -05:00
|
|
|
remove_marker (*item, event);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RegionItem:
|
2010-01-01 17:11:15 -05:00
|
|
|
if (eff == MouseObject) {
|
2005-09-25 14:42:24 -04:00
|
|
|
remove_clicked_region ();
|
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-06-30 14:41:50 -04:00
|
|
|
case ControlPointItem:
|
2011-07-17 16:10:31 -04:00
|
|
|
remove_control_point (item);
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
2010-05-24 21:39:45 -04:00
|
|
|
case NoteItem:
|
|
|
|
remove_midi_note (item, event);
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (event->button.button) {
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
switch (item_type) {
|
|
|
|
/* see comments in button_press_handler */
|
|
|
|
case PlayheadCursorItem:
|
|
|
|
case MarkerItem:
|
|
|
|
case GainLineItem:
|
2007-06-30 14:41:50 -04:00
|
|
|
case AutomationLineItem:
|
2005-09-25 14:42:24 -04:00
|
|
|
case StartSelectionTrimItem:
|
|
|
|
case EndSelectionTrimItem:
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
case MarkerBarItem:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (!_dragging_playhead) {
|
2009-08-24 16:26:34 -04:00
|
|
|
snap_to_with_modifier (where, event, 0, true);
|
2008-12-12 09:43:24 -05:00
|
|
|
mouse_add_new_marker (where);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
case CdMarkerBarItem:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (!_dragging_playhead) {
|
|
|
|
// if we get here then a dragged range wasn't done
|
2009-08-24 16:26:34 -04:00
|
|
|
snap_to_with_modifier (where, event, 0, true);
|
2008-12-12 09:43:24 -05:00
|
|
|
mouse_add_new_marker (where, true);
|
2008-01-10 16:20:59 -05:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case TempoBarItem:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (!_dragging_playhead) {
|
2009-08-24 16:26:34 -04:00
|
|
|
snap_to_with_modifier (where, event);
|
2008-12-12 09:43:24 -05:00
|
|
|
mouse_add_new_tempo_event (where);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MeterBarItem:
|
2008-12-12 09:43:24 -05:00
|
|
|
if (!_dragging_playhead) {
|
2013-04-12 11:15:45 -04:00
|
|
|
mouse_add_new_meter_event (pixel_to_sample (event->button.x));
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
2014-06-12 16:06:31 -04:00
|
|
|
case TimecodeRulerItem:
|
|
|
|
case SamplesRulerItem:
|
|
|
|
case MinsecRulerItem:
|
|
|
|
case BBTRulerItem:
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-01 17:11:15 -05:00
|
|
|
switch (eff) {
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseObject:
|
|
|
|
switch (item_type) {
|
|
|
|
case AutomationTrackItem:
|
2009-07-09 13:58:13 -04:00
|
|
|
atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
|
2008-02-16 17:43:18 -05:00
|
|
|
if (atv) {
|
2014-02-19 12:54:00 -05:00
|
|
|
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
2014-02-19 23:37:46 -05:00
|
|
|
atv->add_automation_event (event, where, event->button.y, with_guard_points);
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MouseGain:
|
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
2010-05-26 21:08:37 -04:00
|
|
|
{
|
2008-12-12 09:43:24 -05:00
|
|
|
/* check that we didn't drag before releasing, since
|
|
|
|
its really annoying to create new control
|
|
|
|
points when doing this.
|
|
|
|
*/
|
2010-05-26 21:08:37 -04:00
|
|
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (clicked_regionview);
|
2012-03-09 15:47:40 -05:00
|
|
|
if (!were_dragging && arv) {
|
2014-02-19 12:54:00 -05:00
|
|
|
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
2014-02-20 14:01:40 -05:00
|
|
|
arv->add_gain_point_event (item, event, with_guard_points);
|
2008-12-12 09:43:24 -05:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2010-05-26 21:08:37 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-02-19 23:37:46 -05:00
|
|
|
case AutomationTrackItem: {
|
2014-02-19 12:54:00 -05:00
|
|
|
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
2009-07-09 13:58:13 -04:00
|
|
|
dynamic_cast<AutomationTimeAxisView*>(clicked_axisview)->
|
2014-02-19 23:37:46 -05:00
|
|
|
add_automation_event (event, where, event->button.y, with_guard_points);
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2014-02-19 23:37:46 -05:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseAudition:
|
2014-06-18 10:24:59 -04:00
|
|
|
pop_canvas_cursor ();
|
2007-11-07 20:40:25 -05:00
|
|
|
if (scrubbing_direction == 0) {
|
2007-10-11 18:07:47 -04:00
|
|
|
/* no drag, just a click */
|
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
2008-01-10 16:20:59 -05:00
|
|
|
play_selected_region ();
|
2007-10-11 18:07:47 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* make sure we stop */
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->request_transport_speed (0.0);
|
2009-10-23 16:17:20 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-03-08 07:45:23 -05:00
|
|
|
/* do any (de)selection operations that should occur on button release */
|
|
|
|
button_selection (item, event, item_type);
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 2:
|
2010-01-01 17:11:15 -05:00
|
|
|
switch (eff) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
case MouseObject:
|
|
|
|
switch (item_type) {
|
|
|
|
case RegionItem:
|
|
|
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
|
|
|
|
raise_region ();
|
|
|
|
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::TertiaryModifier|Keyboard::SecondaryModifier))) {
|
|
|
|
lower_region ();
|
|
|
|
} else {
|
|
|
|
// Button2 click is unused
|
|
|
|
}
|
|
|
|
return true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-01-19 10:23:51 -05:00
|
|
|
case MouseDraw:
|
|
|
|
return true;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MouseRange:
|
|
|
|
// x_style_paste (where, 1.0);
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case 3:
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-03-08 07:45:23 -05:00
|
|
|
|
2006-03-07 21:50:53 -05:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2005-11-22 00:10:12 -05:00
|
|
|
bool
|
2010-01-01 17:11:15 -05:00
|
|
|
Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
|
|
|
ControlPoint* cp;
|
|
|
|
Marker * marker;
|
|
|
|
double fraction;
|
2010-05-30 16:13:29 -04:00
|
|
|
bool ret = true;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
/* by the time we reach here, entered_regionview and entered trackview
|
|
|
|
* will have already been set as appropriate. Things are done this
|
|
|
|
* way because this method isn't passed a pointer to a variable type of
|
|
|
|
* thing that is entered (which may or may not be canvas item).
|
|
|
|
* (e.g. the actual entered regionview)
|
|
|
|
*/
|
|
|
|
|
|
|
|
choose_canvas_cursor_on_entry (&event->crossing, item_type);
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
switch (item_type) {
|
2007-06-30 14:41:50 -04:00
|
|
|
case ControlPointItem:
|
2007-03-18 02:07:08 -04:00
|
|
|
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
|
|
|
|
cp = static_cast<ControlPoint*>(item->get_data ("control_point"));
|
2013-12-31 11:55:30 -05:00
|
|
|
cp->show ();
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2007-07-06 23:19:04 -04:00
|
|
|
fraction = 1.0 - (cp->get_y() / cp->line().height());
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2014-06-26 15:07:29 -04:00
|
|
|
_verbose_cursor->set (cp->line().get_verbose_cursor_string (fraction));
|
2011-05-02 09:38:16 -04:00
|
|
|
_verbose_cursor->show ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
break;
|
2008-01-10 16:20:59 -05:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case GainLineItem:
|
|
|
|
if (mouse_mode == MouseGain) {
|
2005-11-27 17:35:04 -05:00
|
|
|
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
2013-04-04 00:32:52 -04:00
|
|
|
if (line) {
|
2013-04-16 23:46:22 -04:00
|
|
|
line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredGainLine());
|
2013-04-04 00:32:52 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-06-30 14:41:50 -04:00
|
|
|
case AutomationLineItem:
|
2007-03-18 02:07:08 -04:00
|
|
|
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
|
2012-01-30 17:53:22 -05:00
|
|
|
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
|
|
|
if (line) {
|
2013-04-16 23:46:22 -04:00
|
|
|
line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredAutomationLine());
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
2010-06-17 08:45:51 -04:00
|
|
|
}
|
2014-05-30 21:53:59 -04:00
|
|
|
break;
|
2010-06-17 08:45:51 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case AutomationTrackItem:
|
2014-06-18 10:24:59 -04:00
|
|
|
AutomationTimeAxisView* atv;
|
|
|
|
if ((atv = static_cast<AutomationTimeAxisView*>(item->get_data ("trackview"))) != 0) {
|
|
|
|
clear_entered_track = false;
|
|
|
|
set_entered_track (atv);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MarkerItem:
|
2005-11-28 17:36:26 -05:00
|
|
|
if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
}
|
2007-11-12 17:23:01 -05:00
|
|
|
entered_marker = marker;
|
2013-04-16 23:46:22 -04:00
|
|
|
marker->set_color_rgba (ARDOUR_UI::config()->get_canvasvar_EnteredMarker());
|
2005-09-25 14:42:24 -04:00
|
|
|
// fall through
|
|
|
|
case MeterMarkerItem:
|
|
|
|
case TempoMarkerItem:
|
|
|
|
break;
|
2010-06-17 18:09:07 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case FadeInHandleItem:
|
2014-05-31 08:04:41 -04:00
|
|
|
case FadeInTrimHandleItem:
|
|
|
|
if (mouse_mode == MouseObject && !internal_editing()) {
|
|
|
|
ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
|
|
|
|
if (rect) {
|
|
|
|
RegionView* rv = static_cast<RegionView*>(item->get_data ("regionview"));
|
|
|
|
rect->set_fill_color (rv->get_fill_color());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case FadeOutHandleItem:
|
2014-05-31 08:04:41 -04:00
|
|
|
case FadeOutTrimHandleItem:
|
|
|
|
if (mouse_mode == MouseObject && !internal_editing()) {
|
|
|
|
ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
|
|
|
|
if (rect) {
|
|
|
|
RegionView* rv = static_cast<RegionView*>(item->get_data ("regionview"));
|
|
|
|
rect->set_fill_color (rv->get_fill_color ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2010-07-06 07:33:27 -04:00
|
|
|
case FeatureLineItem:
|
2013-04-04 00:32:52 -04:00
|
|
|
{
|
|
|
|
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
|
|
|
line->set_outline_color (0xFF0000FF);
|
|
|
|
}
|
|
|
|
break;
|
2014-03-11 22:38:48 -04:00
|
|
|
|
2010-08-18 14:06:31 -04:00
|
|
|
case SelectionItem:
|
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
/* third pass to handle entered track status in a comprehensible way.
|
2005-09-25 14:42:24 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
switch (item_type) {
|
|
|
|
case GainLineItem:
|
2007-06-30 14:41:50 -04:00
|
|
|
case AutomationLineItem:
|
|
|
|
case ControlPointItem:
|
2005-09-25 14:42:24 -04:00
|
|
|
/* these do not affect the current entered track state */
|
|
|
|
clear_entered_track = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AutomationTrackItem:
|
|
|
|
/* handled above already */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2014-06-18 10:24:59 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-30 16:13:29 -04:00
|
|
|
return ret;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2005-11-22 00:10:12 -05:00
|
|
|
bool
|
2011-09-30 13:55:14 -04:00
|
|
|
Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
|
|
|
AutomationLine* al;
|
|
|
|
Marker *marker;
|
|
|
|
Location *loc;
|
|
|
|
bool is_start;
|
2010-11-25 15:37:39 -05:00
|
|
|
bool ret = true;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
switch (item_type) {
|
2007-06-30 14:41:50 -04:00
|
|
|
case ControlPointItem:
|
2014-06-26 15:07:29 -04:00
|
|
|
_verbose_cursor->hide ();
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case GainLineItem:
|
2007-06-30 14:41:50 -04:00
|
|
|
case AutomationLineItem:
|
2005-11-28 17:36:26 -05:00
|
|
|
al = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
|
2005-11-27 17:35:04 -05:00
|
|
|
{
|
|
|
|
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
2013-04-04 00:32:52 -04:00
|
|
|
if (line) {
|
|
|
|
line->set_outline_color (al->get_line_color());
|
|
|
|
}
|
2005-11-27 17:35:04 -05:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
case MarkerItem:
|
2005-11-28 17:36:26 -05:00
|
|
|
if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
}
|
2007-11-12 17:23:01 -05:00
|
|
|
entered_marker = 0;
|
|
|
|
if ((loc = find_location_from_marker (marker, is_start)) != 0) {
|
2014-09-19 22:50:50 -04:00
|
|
|
location_flags_changed (loc);
|
2007-11-12 17:23:01 -05:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
// fall through
|
|
|
|
case MeterMarkerItem:
|
|
|
|
case TempoMarkerItem:
|
|
|
|
break;
|
|
|
|
|
2014-05-30 22:51:02 -04:00
|
|
|
case FadeInTrimHandleItem:
|
|
|
|
case FadeOutTrimHandleItem:
|
2005-09-25 14:42:24 -04:00
|
|
|
case FadeInHandleItem:
|
|
|
|
case FadeOutHandleItem:
|
2014-06-18 10:24:59 -04:00
|
|
|
{
|
|
|
|
ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
|
|
|
|
if (rect) {
|
|
|
|
rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_InactiveFadeHandle());
|
2005-11-27 17:35:04 -05:00
|
|
|
}
|
2014-06-18 10:24:59 -04:00
|
|
|
}
|
|
|
|
break;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
case AutomationTrackItem:
|
|
|
|
break;
|
2014-06-18 10:24:59 -04:00
|
|
|
|
2010-07-06 07:33:27 -04:00
|
|
|
case FeatureLineItem:
|
2014-06-18 10:24:59 -04:00
|
|
|
{
|
|
|
|
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
|
|
|
|
line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine());
|
|
|
|
}
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-30 16:13:29 -04:00
|
|
|
return ret;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
void
|
2010-09-17 14:20:37 -04:00
|
|
|
Editor::scrub (framepos_t frame, double current_x)
|
2008-04-11 10:06:50 -04:00
|
|
|
{
|
|
|
|
double delta;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
if (scrubbing_direction == 0) {
|
|
|
|
/* first move */
|
2010-01-12 11:14:49 -05:00
|
|
|
_session->request_locate (frame, false);
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->request_transport_speed (0.1);
|
2008-04-11 10:06:50 -04:00
|
|
|
scrubbing_direction = 1;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
} else {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (last_scrub_x > current_x) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
/* pointer moved to the left */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
if (scrubbing_direction > 0) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
/* we reversed direction to go backwards */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
scrub_reversals++;
|
2010-01-12 11:14:49 -05:00
|
|
|
scrub_reverse_distance += (int) (last_scrub_x - current_x);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
} else {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
/* still moving to the left (backwards) */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
scrub_reversals = 0;
|
|
|
|
scrub_reverse_distance = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
delta = 0.01 * (last_scrub_x - current_x);
|
2011-02-06 20:12:47 -05:00
|
|
|
_session->request_transport_speed_nonzero (_session->transport_speed() - delta);
|
2008-04-11 10:06:50 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
} else {
|
|
|
|
/* pointer moved to the right */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
if (scrubbing_direction < 0) {
|
|
|
|
/* we reversed direction to go forward */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
scrub_reversals++;
|
2010-01-12 11:14:49 -05:00
|
|
|
scrub_reverse_distance += (int) (current_x - last_scrub_x);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
} else {
|
|
|
|
/* still moving to the right */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
scrub_reversals = 0;
|
|
|
|
scrub_reverse_distance = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
delta = 0.01 * (current_x - last_scrub_x);
|
2011-02-06 20:12:47 -05:00
|
|
|
_session->request_transport_speed_nonzero (_session->transport_speed() + delta);
|
2008-04-11 10:06:50 -04:00
|
|
|
}
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
/* if there have been more than 2 opposite motion moves detected, or one that moves
|
|
|
|
back more than 10 pixels, reverse direction
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
if (scrub_reversals >= 2 || scrub_reverse_distance > 10) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
if (scrubbing_direction > 0) {
|
|
|
|
/* was forwards, go backwards */
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->request_transport_speed (-0.1);
|
2008-04-11 10:06:50 -04:00
|
|
|
scrubbing_direction = -1;
|
|
|
|
} else {
|
|
|
|
/* was backwards, go forwards */
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->request_transport_speed (0.1);
|
2008-04-11 10:06:50 -04:00
|
|
|
scrubbing_direction = 1;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-04-11 10:06:50 -04:00
|
|
|
scrub_reverse_distance = 0;
|
|
|
|
scrub_reversals = 0;
|
|
|
|
}
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
last_scrub_x = current_x;
|
2008-04-11 10:06:50 -04:00
|
|
|
}
|
|
|
|
|
2005-11-22 00:10:12 -05:00
|
|
|
bool
|
2009-07-21 11:55:17 -04:00
|
|
|
Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from_autoscroll)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2010-08-18 14:06:31 -04:00
|
|
|
_last_motion_y = event->motion.y;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
if (event->motion.is_hint) {
|
|
|
|
gint x, y;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
/* We call this so that MOTION_NOTIFY events continue to be
|
|
|
|
delivered to the canvas. We need to do this because we set
|
|
|
|
Gdk::POINTER_MOTION_HINT_MASK on the canvas. This reduces
|
|
|
|
the density of the events, at the expense of a round-trip
|
|
|
|
to the server. Given that this will mostly occur on cases
|
|
|
|
where DISPLAY = :0.0, and given the cost of what the motion
|
2009-10-14 12:10:01 -04:00
|
|
|
event might do, its a good tradeoff.
|
2008-01-10 16:20:59 -05:00
|
|
|
*/
|
2008-09-10 17:27:39 -04:00
|
|
|
|
2013-04-04 00:32:52 -04:00
|
|
|
_track_canvas->get_pointer (x, y);
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2008-09-10 11:03:30 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
if (current_stepping_trackview) {
|
|
|
|
/* don't keep the persistent stepped trackview if the mouse moves */
|
2009-07-09 13:58:13 -04:00
|
|
|
current_stepping_trackview = 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
step_timeout.disconnect ();
|
|
|
|
}
|
2014-06-26 15:07:29 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
if (_session && _session->actively_recording()) {
|
2005-09-25 14:42:24 -04:00
|
|
|
/* Sorry. no dragging stuff around while we record */
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2014-06-26 15:07:29 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
update_join_object_range_location (event->motion.y);
|
2014-06-26 15:07:29 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (_drags->active ()) {
|
2014-06-26 15:07:29 -04:00
|
|
|
return _drags->motion_handler (event, from_autoscroll);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2014-06-26 15:07:29 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-07-17 16:10:31 -04:00
|
|
|
bool
|
|
|
|
Editor::can_remove_control_point (ArdourCanvas::Item* item)
|
2008-04-11 10:06:50 -04:00
|
|
|
{
|
2009-05-30 14:25:59 -04:00
|
|
|
ControlPoint* control_point;
|
2008-04-11 10:06:50 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if ((control_point = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"))) == 0) {
|
|
|
|
fatal << _("programming error: control point canvas item has no control point object pointer!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
2008-04-11 10:06:50 -04:00
|
|
|
|
2011-07-17 16:10:31 -04:00
|
|
|
AutomationLine& line = control_point->line ();
|
|
|
|
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
|
|
|
|
/* we shouldn't remove the first or last gain point in region gain lines */
|
|
|
|
if (line.is_last_point(*control_point) || line.is_first_point(*control_point)) {
|
|
|
|
return false;
|
|
|
|
}
|
2008-04-11 10:06:50 -04:00
|
|
|
}
|
|
|
|
|
2011-07-17 16:10:31 -04:00
|
|
|
return true;
|
2008-04-11 10:06:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-07-17 16:10:31 -04:00
|
|
|
Editor::remove_control_point (ArdourCanvas::Item* item)
|
2008-04-11 10:06:50 -04:00
|
|
|
{
|
2011-07-17 16:10:31 -04:00
|
|
|
if (!can_remove_control_point (item)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
ControlPoint* control_point;
|
2008-04-11 10:06:50 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if ((control_point = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"))) == 0) {
|
|
|
|
fatal << _("programming error: control point canvas item has no control point object pointer!") << endmsg;
|
2005-09-25 14:42:24 -04:00
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
control_point->line().remove_point (*control_point);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-06-13 03:27:52 -04:00
|
|
|
void
|
2009-05-30 14:25:59 -04:00
|
|
|
Editor::edit_control_point (ArdourCanvas::Item* item)
|
2006-06-13 03:27:52 -04:00
|
|
|
{
|
2009-05-30 14:25:59 -04:00
|
|
|
ControlPoint* p = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
|
2006-06-13 03:27:52 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (p == 0) {
|
|
|
|
fatal << _("programming error: control point canvas item has no control point object pointer!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
2006-06-13 03:27:52 -04:00
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
ControlPointDialog d (p);
|
|
|
|
ensure_float (d);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (d.run () != RESPONSE_ACCEPT) {
|
|
|
|
return;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
p->line().modify_point_y (*p, d.get_y_fraction ());
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2010-08-13 22:00:50 -04:00
|
|
|
void
|
2013-05-02 15:16:56 -04:00
|
|
|
Editor::edit_notes (TimeAxisViewItem& tavi)
|
2010-08-13 22:00:50 -04:00
|
|
|
{
|
2013-05-02 15:16:56 -04:00
|
|
|
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(&tavi);
|
|
|
|
|
|
|
|
if (!mrv) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiRegionView::Selection const & s = mrv->selection();
|
|
|
|
|
2012-06-08 21:51:34 -04:00
|
|
|
if (s.empty ()) {
|
|
|
|
return;
|
|
|
|
}
|
2014-06-18 10:24:59 -04:00
|
|
|
|
2013-05-02 18:13:35 -04:00
|
|
|
EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s);
|
2014-06-18 10:24:59 -04:00
|
|
|
d->show_all ();
|
2013-05-02 18:13:35 -04:00
|
|
|
ensure_float (*d);
|
2010-08-13 22:00:50 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d));
|
2010-08-13 22:00:50 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2013-05-02 18:13:35 -04:00
|
|
|
void
|
|
|
|
Editor::note_edit_done (int r, EditNoteDialog* d)
|
|
|
|
{
|
2014-06-18 10:24:59 -04:00
|
|
|
d->done (r);
|
|
|
|
delete d;
|
2010-08-13 22:00:50 -04:00
|
|
|
}
|
2009-05-30 14:25:59 -04:00
|
|
|
|
2008-12-12 09:43:24 -05:00
|
|
|
void
|
2009-05-30 14:25:59 -04:00
|
|
|
Editor::visible_order_range (int* low, int* high) const
|
2008-12-12 09:43:24 -05:00
|
|
|
{
|
2009-05-30 14:25:59 -04:00
|
|
|
*low = TimeAxisView::max_order ();
|
|
|
|
*high = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
|
|
|
|
2009-07-09 13:58:13 -04:00
|
|
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (!rtv->hidden()) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (*high < rtv->order()) {
|
|
|
|
*high = rtv->order ();
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (*low > rtv->order()) {
|
|
|
|
*low = rtv->order ();
|
|
|
|
}
|
|
|
|
}
|
2008-12-12 09:43:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2009-05-30 14:25:59 -04:00
|
|
|
Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2009-05-30 14:25:59 -04:00
|
|
|
/* Either add to or set the set the region selection, unless
|
|
|
|
this is an alignment click (control used)
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (Keyboard::modifier_state_contains (event->state, Keyboard::PrimaryModifier)) {
|
2009-07-09 13:58:13 -04:00
|
|
|
TimeAxisView* tv = &rv.get_time_axis_view();
|
|
|
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(tv);
|
2009-05-30 14:25:59 -04:00
|
|
|
double speed = 1.0;
|
|
|
|
if (rtv && rtv->is_track()) {
|
2010-04-21 16:42:22 -04:00
|
|
|
speed = rtv->track()->speed();
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2010-09-17 14:20:37 -04:00
|
|
|
framepos_t where = get_preferred_edit_position();
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (where >= 0) {
|
2008-09-10 11:03:30 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-09-17 14:20:37 -04:00
|
|
|
align_region (rv.region(), SyncPoint, (framepos_t) (where * speed));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-09-17 14:20:37 -04:00
|
|
|
align_region (rv.region(), End, (framepos_t) (where * speed));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
} else {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-09-17 14:20:37 -04:00
|
|
|
align_region (rv.region(), Start, (framepos_t) (where * speed));
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
void
|
|
|
|
Editor::collect_new_region_view (RegionView* rv)
|
|
|
|
{
|
|
|
|
latest_regionviews.push_back (rv);
|
|
|
|
}
|
2009-04-20 17:02:46 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
void
|
|
|
|
Editor::collect_and_select_new_region_view (RegionView* rv)
|
|
|
|
{
|
2014-06-18 10:24:59 -04:00
|
|
|
selection->add(rv);
|
2009-05-30 14:25:59 -04:00
|
|
|
latest_regionviews.push_back (rv);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
void
|
|
|
|
Editor::cancel_selection ()
|
|
|
|
{
|
|
|
|
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
|
|
|
(*i)->hide_selection ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
selection->clear ();
|
|
|
|
clicked_selection = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2012-11-20 14:43:43 -05:00
|
|
|
void
|
|
|
|
Editor::cancel_time_selection ()
|
|
|
|
{
|
2014-06-18 10:24:59 -04:00
|
|
|
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
2012-11-20 14:43:43 -05:00
|
|
|
(*i)->hide_selection ();
|
|
|
|
}
|
|
|
|
selection->time.clear ();
|
|
|
|
clicked_selection = 0;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
void
|
2010-09-17 14:20:37 -04:00
|
|
|
Editor::point_trim (GdkEvent* event, framepos_t new_bound)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2006-07-23 08:03:19 -04:00
|
|
|
RegionView* rv = clicked_regionview;
|
2009-04-20 17:02:46 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
/* Choose action dependant on which button was pressed */
|
|
|
|
switch (event->button.button) {
|
|
|
|
case 1:
|
2010-09-14 20:33:33 -04:00
|
|
|
begin_reversible_command (_("start point trim"));
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
if (selection->selected (rv)) {
|
2006-07-23 08:03:19 -04:00
|
|
|
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
|
|
|
|
i != selection->regions.by_layer().end(); ++i)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2006-08-29 17:21:48 -04:00
|
|
|
if (!(*i)->region()->locked()) {
|
2010-08-25 13:32:08 -04:00
|
|
|
(*i)->region()->clear_changes ();
|
2011-05-30 09:54:44 -04:00
|
|
|
(*i)->region()->trim_front (new_bound);
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command(new StatefulDiffCommand ((*i)->region()));
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2006-08-29 17:21:48 -04:00
|
|
|
if (!rv->region()->locked()) {
|
2010-08-25 13:32:08 -04:00
|
|
|
rv->region()->clear_changes ();
|
2011-05-30 09:54:44 -04:00
|
|
|
rv->region()->trim_front (new_bound);
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command(new StatefulDiffCommand (rv->region()));
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
commit_reversible_command();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
begin_reversible_command (_("End point trim"));
|
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
if (selection->selected (rv)) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-07-23 08:03:19 -04:00
|
|
|
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2006-08-29 17:21:48 -04:00
|
|
|
if (!(*i)->region()->locked()) {
|
2010-08-25 13:32:08 -04:00
|
|
|
(*i)->region()->clear_changes();
|
2011-05-30 09:54:44 -04:00
|
|
|
(*i)->region()->trim_end (new_bound);
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command(new StatefulDiffCommand ((*i)->region()));
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
} else {
|
2006-06-13 03:27:52 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (!rv->region()->locked()) {
|
2010-08-25 13:32:08 -04:00
|
|
|
rv->region()->clear_changes ();
|
2011-05-30 09:54:44 -04:00
|
|
|
rv->region()->trim_end (new_bound);
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command (new StatefulDiffCommand (rv->region()));
|
2006-06-13 03:27:52 -04:00
|
|
|
}
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
commit_reversible_command();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-07-21 11:55:17 -04:00
|
|
|
Editor::hide_marker (ArdourCanvas::Item* item, GdkEvent* /*event*/)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2009-05-30 14:25:59 -04:00
|
|
|
Marker* marker;
|
|
|
|
bool is_start;
|
|
|
|
|
|
|
|
if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
|
|
|
|
fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
|
|
|
|
/*NOTREACHED*/
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-10-14 12:10:01 -04:00
|
|
|
Location* location = find_location_from_marker (marker, is_start);
|
2009-05-30 14:25:59 -04:00
|
|
|
location->set_hidden (true, this);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2010-09-17 14:20:37 -04:00
|
|
|
Editor::reposition_zoom_rect (framepos_t start, framepos_t end)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2013-04-12 11:15:45 -04:00
|
|
|
double x1 = sample_to_pixel (start);
|
|
|
|
double x2 = sample_to_pixel (end);
|
2013-04-04 00:32:52 -04:00
|
|
|
double y2 = _full_canvas_height - 1.0;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2013-04-04 18:45:27 -04:00
|
|
|
zoom_rect->set (ArdourCanvas::Rect (x1, 1.0, x2, y2));
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gint
|
2009-07-21 11:55:17 -04:00
|
|
|
Editor::mouse_rename_region (ArdourCanvas::Item* /*item*/, GdkEvent* /*event*/)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2005-09-25 16:33:00 -04:00
|
|
|
using namespace Gtkmm2ext;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
ArdourPrompter prompter (false);
|
|
|
|
|
|
|
|
prompter.set_prompt (_("Name for region:"));
|
2006-08-29 17:21:48 -04:00
|
|
|
prompter.set_initial_text (clicked_regionview->region()->name());
|
2006-04-19 16:42:17 -04:00
|
|
|
prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
|
2006-04-22 11:28:59 -04:00
|
|
|
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
2005-09-25 14:42:24 -04:00
|
|
|
prompter.show_all ();
|
2005-10-26 21:10:36 -04:00
|
|
|
switch (prompter.run ()) {
|
2006-01-13 14:48:55 -05:00
|
|
|
case Gtk::RESPONSE_ACCEPT:
|
2007-08-10 16:55:27 -04:00
|
|
|
string str;
|
2005-10-26 21:10:36 -04:00
|
|
|
prompter.get_result(str);
|
|
|
|
if (str.length()) {
|
2007-04-29 13:23:11 -04:00
|
|
|
clicked_regionview->region()->set_name (str);
|
2005-10-26 21:10:36 -04:00
|
|
|
}
|
|
|
|
break;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2010-09-17 14:20:37 -04:00
|
|
|
Editor::mouse_brush_insert_region (RegionView* rv, framepos_t pos)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
|
|
|
/* no brushing without a useful snap setting */
|
|
|
|
|
2009-10-26 19:43:04 -04:00
|
|
|
switch (_snap_mode) {
|
2005-09-25 14:42:24 -04:00
|
|
|
case SnapMagnetic:
|
|
|
|
return; /* can't work because it allows region to be placed anywhere */
|
|
|
|
default:
|
|
|
|
break; /* OK */
|
|
|
|
}
|
|
|
|
|
2009-10-26 19:43:04 -04:00
|
|
|
switch (_snap_type) {
|
2005-09-25 14:42:24 -04:00
|
|
|
case SnapToMark:
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't brush a copy over the original */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2006-08-29 17:21:48 -04:00
|
|
|
if (pos == rv->region()->position()) {
|
2005-09-25 14:42:24 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-07-09 13:58:13 -04:00
|
|
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
if (rtv == 0 || !rtv->is_track()) {
|
2005-09-25 14:42:24 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
boost::shared_ptr<Playlist> playlist = rtv->playlist();
|
2010-04-21 16:42:22 -04:00
|
|
|
double speed = rtv->track()->speed();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
playlist->clear_changes ();
|
2011-02-14 16:49:43 -05:00
|
|
|
boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region(), true));
|
2010-11-25 15:37:39 -05:00
|
|
|
playlist->add_region (new_region, (framepos_t) (pos * speed));
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command (new StatefulDiffCommand (playlist));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-25 15:34:09 -05:00
|
|
|
// playlist is frozen, so we have to update manually XXX this is disgusting
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-25 15:34:09 -05:00
|
|
|
playlist->RegionAdded (new_region); /* EMIT SIGNAL */
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
Editor::track_height_step_timeout ()
|
|
|
|
{
|
2008-09-10 11:03:30 -04:00
|
|
|
if (get_microseconds() - last_track_height_step_timestamp < 250000) {
|
2009-07-09 13:58:13 -04:00
|
|
|
current_stepping_trackview = 0;
|
2006-03-07 21:50:53 -05:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-03-07 21:50:53 -05:00
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2007-10-11 18:07:47 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
void
|
2011-09-30 13:55:14 -04:00
|
|
|
Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region_view)
|
2009-05-30 14:25:59 -04:00
|
|
|
{
|
|
|
|
assert (region_view);
|
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!region_view->region()->playlist()) {
|
|
|
|
return;
|
|
|
|
}
|
2010-09-16 17:58:54 -04:00
|
|
|
|
Ripple mode: basic implementation
Add a value for Ripple to EditMode enum.
Add Ripple edit mode to edit mode dropdown, by adding it to the
Editor::build_edit_mode_menu() helper function, and remove the old code that
added items to the (now unused) Editor::edit_mode_strings.
Add the regions that should be affected by the drag to RegionDrag::_views so
that the drag carries them along automatically.
Use a copy of the RegionList in Playlist::core_ripple(), since bad things
happen when iterating over regions and they get moved around in the list.
Handle rippling in removal of regions from playlist.
When dragging in ripple mode, exclude all regions that lie before the
original start position of the selected regions being dragged from
rippling: this is what Mixbus does.
Make editor dragging respect snap-to settings, by using the existing
compute_x_delta() function, which did almost the right thing. Move setting
of _last_frame_position out of that function so all ripple-dragged regions
can move.
Ripple when dragging from region list: even though Mixbus doesn't do this, it
seems like a good idea.
Prevent multi-track selection being dragged across tracks, by making
RegionMotionDrag::y_movement_allowed() virtual, and overriding it in
RegionRippleDrag to forbid dragging of selections containing regions on more
than one track to dofferent tracks in ripple mode.
Remember which TimeAxisView a ripple-mode drag that's allowed cross-track
drags started from, so that the effect of rippling regions after any region
that's dragged off that track can be undone.
2013-10-23 16:50:01 -04:00
|
|
|
switch (Config->get_edit_mode()) {
|
|
|
|
case Splice:
|
|
|
|
_drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer()));
|
|
|
|
break;
|
|
|
|
case Ripple:
|
|
|
|
_drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer()));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
_drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false));
|
|
|
|
break;
|
2014-07-01 14:10:47 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-09-30 13:55:14 -04:00
|
|
|
Editor::add_region_copy_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region_view)
|
2009-05-30 14:25:59 -04:00
|
|
|
{
|
|
|
|
assert (region_view);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!region_view->region()->playlist()) {
|
|
|
|
return;
|
|
|
|
}
|
2010-09-16 17:58:54 -04:00
|
|
|
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, true));
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-09-30 13:55:14 -04:00
|
|
|
Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region_view)
|
2009-05-30 14:25:59 -04:00
|
|
|
{
|
|
|
|
assert (region_view);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
if (!region_view->region()->playlist()) {
|
|
|
|
return;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
Ripple mode: basic implementation
Add a value for Ripple to EditMode enum.
Add Ripple edit mode to edit mode dropdown, by adding it to the
Editor::build_edit_mode_menu() helper function, and remove the old code that
added items to the (now unused) Editor::edit_mode_strings.
Add the regions that should be affected by the drag to RegionDrag::_views so
that the drag carries them along automatically.
Use a copy of the RegionList in Playlist::core_ripple(), since bad things
happen when iterating over regions and they get moved around in the list.
Handle rippling in removal of regions from playlist.
When dragging in ripple mode, exclude all regions that lie before the
original start position of the selected regions being dragged from
rippling: this is what Mixbus does.
Make editor dragging respect snap-to settings, by using the existing
compute_x_delta() function, which did almost the right thing. Move setting
of _last_frame_position out of that function so all ripple-dragged regions
can move.
Ripple when dragging from region list: even though Mixbus doesn't do this, it
seems like a good idea.
Prevent multi-track selection being dragged across tracks, by making
RegionMotionDrag::y_movement_allowed() virtual, and overriding it in
RegionRippleDrag to forbid dragging of selections containing regions on more
than one track to dofferent tracks in ripple mode.
Remember which TimeAxisView a ripple-mode drag that's allowed cross-track
drags started from, so that the effect of rippling regions after any region
that's dragged off that track can be undone.
2013-10-23 16:50:01 -04:00
|
|
|
if (Config->get_edit_mode() == Splice || Config->get_edit_mode() == Ripple) {
|
2009-05-30 14:25:59 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-10 12:51:59 -04:00
|
|
|
_drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true, false));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2011-01-19 12:38:56 -05:00
|
|
|
begin_reversible_command (Operations::drag_region_brush);
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Start a grab where a time range is selected, track(s) are selected, and the
|
|
|
|
* user clicks and drags a region with a modifier in order to create a new region containing
|
|
|
|
* the section of the clicked region that lies within the time range.
|
|
|
|
*/
|
|
|
|
void
|
2009-07-21 11:55:17 -04:00
|
|
|
Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
|
2009-05-30 14:25:59 -04:00
|
|
|
{
|
|
|
|
if (clicked_regionview == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* lets try to create new Region for the selection */
|
|
|
|
|
|
|
|
vector<boost::shared_ptr<Region> > new_regions;
|
|
|
|
create_region_from_selection (new_regions);
|
|
|
|
|
|
|
|
if (new_regions.empty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX fix me one day to use all new regions */
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
boost::shared_ptr<Region> region (new_regions.front());
|
|
|
|
|
|
|
|
/* add it to the current stream/playlist.
|
|
|
|
|
|
|
|
tricky: the streamview for the track will add a new regionview. we will
|
|
|
|
catch the signal it sends when it creates the regionview to
|
|
|
|
set the regionview we want to then drag.
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
latest_regionviews.clear();
|
2009-12-11 18:29:48 -05:00
|
|
|
sigc::connection c = clicked_routeview->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
|
|
|
/* A selection grab currently creates two undo/redo operations, one for
|
2009-05-30 14:25:59 -04:00
|
|
|
creating the new region and another for moving it.
|
|
|
|
*/
|
|
|
|
|
2011-01-19 12:38:56 -05:00
|
|
|
begin_reversible_command (Operations::selection_grab);
|
2009-05-30 14:25:59 -04:00
|
|
|
|
|
|
|
boost::shared_ptr<Playlist> playlist = clicked_axisview->playlist();
|
|
|
|
|
2010-11-25 15:37:39 -05:00
|
|
|
playlist->clear_changes ();
|
2009-05-30 14:25:59 -04:00
|
|
|
clicked_routeview->playlist()->add_region (region, selection->time[clicked_selection].start);
|
2010-03-02 13:05:26 -05:00
|
|
|
_session->add_command(new StatefulDiffCommand (playlist));
|
2009-05-30 14:25:59 -04:00
|
|
|
|
|
|
|
commit_reversible_command ();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
c.disconnect ();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-30 14:25:59 -04:00
|
|
|
if (latest_regionviews.empty()) {
|
|
|
|
/* something went wrong */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we need to deselect all other regionviews, and select this one
|
2009-10-14 12:10:01 -04:00
|
|
|
i'm ignoring undo stuff, because the region creation will take care of it
|
2009-05-30 14:25:59 -04:00
|
|
|
*/
|
|
|
|
selection->set (latest_regionviews);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
_drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false), event);
|
2009-05-30 14:25:59 -04:00
|
|
|
}
|
|
|
|
|
2010-01-07 20:28:15 -05:00
|
|
|
void
|
|
|
|
Editor::escape ()
|
|
|
|
{
|
2010-01-12 11:14:49 -05:00
|
|
|
if (_drags->active ()) {
|
2010-05-05 18:09:07 -04:00
|
|
|
_drags->abort ();
|
2010-01-07 20:28:15 -05:00
|
|
|
} else {
|
|
|
|
selection->clear ();
|
|
|
|
}
|
2014-09-16 11:09:12 -04:00
|
|
|
|
|
|
|
reset_focus ();
|
2010-01-07 20:28:15 -05:00
|
|
|
}
|
|
|
|
|
2009-07-28 16:51:28 -04:00
|
|
|
void
|
|
|
|
Editor::set_internal_edit (bool yn)
|
|
|
|
{
|
2012-02-13 09:34:21 -05:00
|
|
|
if (_internal_editing == yn) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-07-28 16:51:28 -04:00
|
|
|
_internal_editing = yn;
|
2014-06-18 10:24:59 -04:00
|
|
|
|
2009-08-17 11:58:47 -04:00
|
|
|
if (yn) {
|
2014-06-18 10:24:59 -04:00
|
|
|
pre_internal_mouse_mode = mouse_mode;
|
2012-02-13 09:34:21 -05:00
|
|
|
pre_internal_snap_type = _snap_type;
|
|
|
|
pre_internal_snap_mode = _snap_mode;
|
2011-03-07 20:55:50 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
|
|
|
(*i)->enter_internal_edit_mode ();
|
|
|
|
}
|
2011-03-03 09:51:02 -05:00
|
|
|
|
2012-02-13 09:34:21 -05:00
|
|
|
set_snap_to (internal_snap_type);
|
|
|
|
set_snap_mode (internal_snap_mode);
|
|
|
|
|
2009-08-17 11:58:47 -04:00
|
|
|
} else {
|
2012-02-13 09:34:21 -05:00
|
|
|
|
|
|
|
internal_snap_mode = _snap_mode;
|
|
|
|
internal_snap_type = _snap_type;
|
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
|
|
|
(*i)->leave_internal_edit_mode ();
|
|
|
|
}
|
2011-03-07 20:55:50 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) {
|
|
|
|
/* we were drawing .. flip back to something sensible */
|
|
|
|
set_mouse_mode (pre_internal_mouse_mode);
|
|
|
|
}
|
2012-02-13 09:34:21 -05:00
|
|
|
|
|
|
|
set_snap_to (pre_internal_snap_type);
|
|
|
|
set_snap_mode (pre_internal_snap_mode);
|
2010-05-24 21:13:45 -04:00
|
|
|
}
|
2014-06-18 10:24:59 -04:00
|
|
|
|
|
|
|
reset_canvas_cursor ();
|
2009-07-28 16:51:28 -04:00
|
|
|
}
|
2010-01-01 17:11:15 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
/** Update _join_object_range_state which indicate whether we are over the top
|
|
|
|
* or bottom half of a route view, used by the `join object/range' tool
|
|
|
|
* mode. Coordinates in canvas space.
|
2010-01-01 17:11:15 -05:00
|
|
|
*/
|
|
|
|
void
|
2014-06-18 10:24:59 -04:00
|
|
|
Editor::update_join_object_range_location (double y)
|
2010-01-01 17:11:15 -05:00
|
|
|
{
|
2014-06-18 10:24:59 -04:00
|
|
|
if (_internal_editing || !get_smart_mode()) {
|
2010-01-01 17:11:15 -05:00
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_NONE;
|
|
|
|
return;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
JoinObjectRangeState const old = _join_object_range_state;
|
|
|
|
|
2010-01-12 11:14:49 -05:00
|
|
|
if (mouse_mode == MouseObject) {
|
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
|
|
|
|
} else if (mouse_mode == MouseRange) {
|
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
|
|
|
|
}
|
2010-01-01 20:19:47 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
if (entered_regionview) {
|
2010-01-01 17:11:15 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
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();
|
|
|
|
|
|
|
|
_join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
|
|
|
|
|
|
|
|
if (_join_object_range_state != old) {
|
2014-06-18 21:03:25 -04:00
|
|
|
set_canvas_cursor (which_track_cursor ());
|
2014-06-18 10:24:59 -04:00
|
|
|
}
|
2010-01-12 11:14:49 -05:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
} else if (entered_track) {
|
2010-09-21 19:26:18 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
RouteTimeAxisView* entered_route_view = dynamic_cast<RouteTimeAxisView*> (entered_track);
|
|
|
|
|
|
|
|
if (entered_route_view) {
|
2014-07-02 16:23:46 -04:00
|
|
|
|
|
|
|
double cx = 0;
|
|
|
|
double cy = y;
|
|
|
|
|
|
|
|
entered_route_view->canvas_display()->canvas_to_item (cx, cy);
|
|
|
|
|
|
|
|
double track_height = entered_route_view->view()->child_height();
|
|
|
|
if (Config->get_show_name_highlight()) {
|
|
|
|
track_height -= TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
|
|
|
|
}
|
|
|
|
double const c = cy / track_height;
|
|
|
|
|
|
|
|
|
|
|
|
if (c <= 0.5) {
|
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
|
|
|
|
} else {
|
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
|
2014-06-18 10:24:59 -04:00
|
|
|
}
|
2014-07-02 16:23:46 -04:00
|
|
|
|
2014-06-18 10:24:59 -04:00
|
|
|
} else {
|
|
|
|
/* Other kinds of tracks use object mode */
|
|
|
|
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
|
2014-07-02 16:23:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_join_object_range_state != old) {
|
|
|
|
set_canvas_cursor (which_track_cursor ());
|
2010-01-01 17:11:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Editing::MouseMode
|
|
|
|
Editor::effective_mouse_mode () const
|
|
|
|
{
|
|
|
|
if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
|
|
|
|
return MouseObject;
|
|
|
|
} else if (_join_object_range_state == JOIN_OBJECT_RANGE_RANGE) {
|
|
|
|
return MouseRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mouse_mode;
|
|
|
|
}
|
2010-05-24 21:39:45 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
Editor::remove_midi_note (ArdourCanvas::Item* item, GdkEvent *)
|
|
|
|
{
|
2013-04-04 00:32:52 -04:00
|
|
|
NoteBase* e = reinterpret_cast<NoteBase*> (item->get_data ("notebase"));
|
2010-05-24 21:39:45 -04:00
|
|
|
assert (e);
|
|
|
|
|
|
|
|
e->region_view().delete_note (e->note ());
|
|
|
|
}
|
2010-11-15 14:00:31 -05:00
|
|
|
|
2013-04-04 18:45:27 -04:00
|
|
|
/** Obtain the pointer position in canvas coordinates */
|
2011-05-02 09:38:16 -04:00
|
|
|
void
|
|
|
|
Editor::get_pointer_position (double& x, double& y) const
|
|
|
|
{
|
|
|
|
int px, py;
|
2013-04-04 18:45:27 -04:00
|
|
|
_track_canvas->get_pointer (px, py);
|
2013-04-17 10:53:17 -04:00
|
|
|
_track_canvas->window_to_canvas (px, py, x, y);
|
2011-05-02 09:38:16 -04:00
|
|
|
}
|