summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-11-08 01:40:25 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-11-08 01:40:25 +0000
commitbadc087263990ecf360792c10e4d9f2d60828d43 (patch)
tree7e4b7e0afea47be51cbad48f06bb1779f483f56f /gtk2_ardour
parentdf20e5935fbdaf7d27f924e4e2ea87707d8a2314 (diff)
merged with 2.0-ongoing changes 2582-2605 (not thoroughly tested but it compiles, start up, and creates a new session)
git-svn-id: svn://localhost/ardour2/trunk@2606 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc2
-rw-r--r--gtk2_ardour/editing.h11
-rw-r--r--gtk2_ardour/editing_syms.h6
-rw-r--r--gtk2_ardour/editor.cc127
-rw-r--r--gtk2_ardour/editor.h47
-rw-r--r--gtk2_ardour/editor_actions.cc58
-rw-r--r--gtk2_ardour/editor_audio_import.cc8
-rw-r--r--gtk2_ardour/editor_canvas_events.cc1
-rw-r--r--gtk2_ardour/editor_markers.cc8
-rw-r--r--gtk2_ardour/editor_mouse.cc257
-rw-r--r--gtk2_ardour/editor_ops.cc133
-rw-r--r--gtk2_ardour/editor_selection.cc15
-rw-r--r--gtk2_ardour/editor_timefx.cc51
-rw-r--r--gtk2_ardour/enums.cc6
-rw-r--r--gtk2_ardour/marker_selection.h31
-rw-r--r--gtk2_ardour/public_editor.h10
-rw-r--r--gtk2_ardour/selection.cc52
-rw-r--r--gtk2_ardour/selection.h10
-rw-r--r--gtk2_ardour/time_axis_view.cc10
-rw-r--r--gtk2_ardour/utils.cc56
-rw-r--r--gtk2_ardour/utils.h2
21 files changed, 596 insertions, 305 deletions
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 74b5a70738..7f4a0a1e69 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -155,7 +155,7 @@ ARDOUR_UI::install_actions ()
Glib::RefPtr<ActionGroup> jack_actions = ActionGroup::create (X_("JACK"));
ActionManager::register_action (jack_actions, X_("JACK"), _("JACK"));
ActionManager::register_action (jack_actions, X_("Latency"), _("Latency"));
-
+
act = ActionManager::register_action (jack_actions, X_("JACKReconnect"), _("Reconnect"), mem_fun (*(ARDOUR_UI::instance()), &ARDOUR_UI::reconnect_to_jack));
ActionManager::jack_opposite_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h
index 93bbb603ee..2b4519ec9c 100644
--- a/gtk2_ardour/editing.h
+++ b/gtk2_ardour/editing.h
@@ -36,6 +36,7 @@
#define IMPORTMODE(a) /*empty*/
#define IMPORTPOSITION(a)
#define IMPORTDISPOSITION(a)
+#define EDITPOINT(a) /*empty*/
namespace Editing {
@@ -168,6 +169,16 @@ enum ImportDisposition {
#undef IMPORTDISPOSITION
#define IMPORTDISPOSITION(a) /*empty*/
+// EDITPOINT
+#undef EDITPOINT
+#define EDITPOINT(a) a,
+enum EditPoint {
+ #include "editing_syms.h"
+};
+
+#undef EDITPOINT
+#define EDITPOINT(a) /*empty*/
+
/////////////////////
// These don't need their state saved. yet...
enum CutCopyOp {
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index f731d33efe..29fd1234a8 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -71,6 +71,7 @@ ZOOMFOCUS(ZoomFocusLeft)
ZOOMFOCUS(ZoomFocusRight)
ZOOMFOCUS(ZoomFocusCenter)
ZOOMFOCUS(ZoomFocusPlayhead)
+ZOOMFOCUS(ZoomFocusMouse)
ZOOMFOCUS(ZoomFocusEdit)
DISPLAYCONTROL(FollowPlayhead)
@@ -95,3 +96,8 @@ IMPORTDISPOSITION(ImportDistinctFiles=0)
IMPORTDISPOSITION(ImportMergeFiles=1)
IMPORTDISPOSITION(ImportSerializeFiles=2)
IMPORTDISPOSITION(ImportDistinctChannels=3)
+
+
+EDITPOINT(EditAtPlayhead)
+EDITPOINT(EditAtSelectedMarker)
+EDITPOINT(EditAtMouse)
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 1e726277d2..bf05cc5485 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -139,11 +139,19 @@ static const gchar *_snap_mode_strings[] = {
0
};
+static const gchar *_edit_point_strings[] = {
+ N_("Playhead"),
+ N_("Marker"),
+ N_("Mouse"),
+ 0
+};
+
static const gchar *_zoom_focus_strings[] = {
N_("Left"),
N_("Right"),
N_("Center"),
N_("Playhead"),
+ N_("Mouse"),
N_("Edit Cursor"),
0
};
@@ -170,20 +178,6 @@ show_me_the_size (Requisition* r, const char* what)
cerr << "size of " << what << " = " << r->width << " x " << r->height << endl;
}
-void
-check_adjustment (Gtk::Adjustment* adj)
-{
- cerr << "CHANGE adj = "
- << adj->get_lower () << ' '
- << adj->get_upper () << ' '
- << adj->get_value () << ' '
- << adj->get_step_increment () << ' '
- << adj->get_page_increment () << ' '
- << adj->get_page_size () << ' '
- << endl;
-
-}
-
Editor::Editor ()
:
/* time display buttons */
@@ -256,14 +250,20 @@ Editor::Editor ()
current_mixer_strip = 0;
current_bbt_points = 0;
- snap_type_strings = I18N (_snap_type_strings);
- snap_mode_strings = I18N (_snap_mode_strings);
- zoom_focus_strings = I18N(_zoom_focus_strings);
+ snap_type_strings = I18N (_snap_type_strings);
+ snap_mode_strings = I18N (_snap_mode_strings);
+ zoom_focus_strings = I18N (_zoom_focus_strings);
+ edit_point_strings = I18N (_edit_point_strings);
snap_type = SnapToFrame;
set_snap_to (snap_type);
+
snap_mode = SnapNormal;
set_snap_mode (snap_mode);
+
+ _edit_point = EditAtMouse;
+ set_edit_point (_edit_point);
+
snap_threshold = 5.0;
bbt_beat_subdivision = 4;
canvas_width = 0;
@@ -329,13 +329,7 @@ Editor::Editor ()
_dragging_playhead = false;
_dragging_hscrollbar = false;
- _scrubbing = false;
- mouse_direction = 1;
- mouse_speed_update = -1;
- mouse_speed_size = 16;
- mouse_speed = new double[mouse_speed_size];
- memset (mouse_speed, 0, sizeof(double) * mouse_speed_size);
- mouse_speed_entries = 0;
+ scrubbing_direction = 0;
sfbrowser = 0;
ignore_route_order_sync = false;
@@ -2005,6 +1999,18 @@ Editor::set_snap_mode (SnapMode mode)
instant_save ();
}
+void
+Editor::set_edit_point (EditPoint ep)
+{
+ _edit_point = ep;
+ string str = edit_point_strings[(int)ep];
+
+ if (str != edit_point_selector.get_active_text ()) {
+ edit_point_selector.set_active_text (str);
+ }
+
+ instant_save ();
+}
int
Editor::set_state (const XMLNode& node)
@@ -2082,6 +2088,10 @@ Editor::set_state (const XMLNode& node)
set_snap_mode ((SnapMode) atoi (prop->value()));
}
+ if ((prop = node.property ("edit-point"))) {
+ set_edit_point ((EditPoint) string_2_enum (prop->value(), _edit_point));
+ }
+
if ((prop = node.property ("mouse-mode"))) {
MouseMode m = str2mousemode(prop->value());
mouse_mode = MouseMode ((int) m + 1); /* lie, force mode switch */
@@ -2233,6 +2243,8 @@ Editor::get_state ()
snprintf (buf, sizeof(buf), "%d", (int) snap_mode);
node->add_property ("snap-mode", buf);
+ node->add_property ("edit-point", enum_2_string (_edit_point));
+
snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
node->add_property ("playhead", buf);
snprintf (buf, sizeof (buf), "%" PRIu32, edit_cursor->current_frame);
@@ -2400,7 +2412,7 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
break;
case SnapToEditCursor:
- start = edit_cursor->current_frame;
+ start = get_preferred_edit_position ();
break;
case SnapToMark:
@@ -2681,17 +2693,24 @@ Editor::setup_toolbar ()
Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10);
set_popdown_strings (snap_type_selector, snap_type_strings);
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
- ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Unit to snap cursors and ranges to"));
+ ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Snap/Grid Units"));
snap_mode_selector.set_name ("SnapModeSelector");
Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10);
set_popdown_strings (snap_mode_selector, snap_mode_strings);
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
+ ARDOUR_UI::instance()->tooltips().set_tip (snap_mode_selector, _("Snap/Grid Mode"));
+
+ edit_point_selector.set_name ("SnapModeSelector");
+ Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, "Playhead", 2+FUDGE, 10);
+ set_popdown_strings (edit_point_selector, edit_point_strings);
+ edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done));
+ ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point"));
snap_box.pack_start (edit_cursor_clock, false, false);
snap_box.pack_start (snap_mode_selector, false, false);
snap_box.pack_start (snap_type_selector, false, false);
-
+ snap_box.pack_start (edit_point_selector, false, false);
/* Nudge */
@@ -2845,8 +2864,6 @@ Editor::convert_drop_to_paths (vector<ustring>& paths,
vector<ustring> uris = data.get_uris();
- cerr << "there were " << uris.size() << " in that drag data\n";
-
if (uris.empty()) {
/* This is seriously fucked up. Nautilus doesn't say that its URI lists
@@ -3229,6 +3246,27 @@ Editor::snap_mode_selection_done ()
}
void
+Editor::edit_point_selection_done ()
+{
+ string choice = edit_point_selector.get_active_text();
+ EditPoint ep = EditAtSelectedMarker;
+
+ if (choice == _("Marker")) {
+ _edit_point = EditAtSelectedMarker;
+ } else if (choice == _("Playhead")) {
+ _edit_point = EditAtPlayhead;
+ } else {
+ _edit_point = EditAtMouse;
+ }
+
+ RefPtr<RadioAction> ract = edit_point_action (ep);
+
+ if (ract) {
+ ract->set_active (true);
+ }
+}
+
+void
Editor::zoom_focus_selection_done ()
{
string choice = zoom_focus_selector.get_active_text();
@@ -3244,6 +3282,8 @@ Editor::zoom_focus_selection_done ()
focus_type = ZoomFocusPlayhead;
} else if (choice == _("Edit")) {
focus_type = ZoomFocusEdit;
+ } else {
+ focus_type = ZoomFocusMouse;
}
RefPtr<RadioAction> ract = zoom_focus_action (focus_type);
@@ -4025,6 +4065,35 @@ Editor::edit_cursor_position(bool sync)
return edit_cursor->current_frame;
}
+nframes64_t
+Editor::get_preferred_edit_position() const
+{
+ bool ignored;
+ nframes64_t where;
+
+ switch (_edit_point) {
+ case EditAtPlayhead:
+ return playhead_cursor->current_frame;
+
+ case EditAtSelectedMarker:
+ if (!selection->markers.empty()) {
+ bool whocares;
+ Location* loc = find_location_from_marker (selection->markers.front(), whocares);
+ if (loc) {
+ return loc->start();
+ }
+ }
+ /* fallthru */
+
+ default:
+ case EditAtMouse:
+ if (mouse_frame (where, ignored)) {
+ return where;
+ }
+ }
+
+ return -1;
+}
void
Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 96c1d1004d..9f68929bfb 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -46,6 +46,7 @@
#include <pbd/stateful.h>
#include <ardour/session.h>
+#include <ardour/stretch.h>
#include <ardour/tempo.h>
#include <ardour/location.h>
#include <ardour/audioregion.h>
@@ -183,15 +184,15 @@ class Editor : public PublicEditor
/* undo related */
- nframes_t unit_to_frame (double unit) {
+ nframes_t unit_to_frame (double unit) const {
return (nframes_t) rint (unit * frames_per_unit);
}
- double frame_to_unit (nframes_t frame) {
+ double frame_to_unit (nframes_t frame) const {
return rint ((double) frame / (double) frames_per_unit);
}
- double frame_to_unit (double frame) {
+ double frame_to_unit (double frame) const {
return rint (frame / frames_per_unit);
}
@@ -202,7 +203,7 @@ class Editor : public PublicEditor
xscroll_adjustment.
*/
- nframes_t pixel_to_frame (double pixel) {
+ nframes64_t pixel_to_frame (double pixel) const {
/* pixel can be less than zero when motion events
are processed. since we've already run the world->canvas
@@ -217,7 +218,7 @@ class Editor : public PublicEditor
}
}
- gulong frame_to_pixel (nframes_t frame) {
+ gulong frame_to_pixel (nframes64_t frame) const {
return (gulong) rint ((frame / (frames_per_unit * GNOME_CANVAS(track_canvas.gobj())->pixels_per_unit)));
}
@@ -354,6 +355,8 @@ class Editor : public PublicEditor
void reposition_and_zoom (nframes_t, double);
nframes_t edit_cursor_position(bool);
+ nframes64_t get_preferred_edit_position () const;
+
bool update_mouse_speed ();
bool decelerate_mouse_speed ();
@@ -424,8 +427,8 @@ class Editor : public PublicEditor
void set_color_rgba (uint32_t);
};
- LocationMarkers *find_location_markers (ARDOUR::Location *);
- ARDOUR::Location* find_location_from_marker (Marker *, bool& is_start);
+ LocationMarkers *find_location_markers (ARDOUR::Location *) const;
+ ARDOUR::Location* find_location_from_marker (Marker *, bool& is_start) const;
typedef std::map<ARDOUR::Location*,LocationMarkers *> LocationMarkerMap;
LocationMarkerMap location_markers;
@@ -1136,16 +1139,8 @@ class Editor : public PublicEditor
void stop_scrolling ();
bool _scrubbing;
- bool have_full_mouse_speed;
- nframes64_t last_scrub_frame;
- double last_scrub_time;
- int mouse_speed_update;
- double mouse_direction;
- double compute_mouse_speed ();
- void add_mouse_speed (double, double);
- double* mouse_speed;
- size_t mouse_speed_entries;
- size_t mouse_speed_size;
+ double last_scrub_x;
+ int scrubbing_direction;
void keyboard_selection_begin ();
void keyboard_selection_finish (bool add);
@@ -1834,14 +1829,18 @@ class Editor : public PublicEditor
void duplicate_dialog (bool for_region);
- nframes_t event_frame (GdkEvent*, double* px = 0, double* py = 0);
+ nframes64_t event_frame (GdkEvent*, double* px = 0, double* py = 0) const;
+
+ /* returns false if mouse pointer is not in track or marker canvas
+ */
+ bool mouse_frame (nframes64_t&, bool& in_track_canvas) const;
void time_fx_motion (ArdourCanvas::Item*, GdkEvent*);
void start_time_fx (ArdourCanvas::Item*, GdkEvent*);
void end_time_fx (ArdourCanvas::Item*, GdkEvent*);
struct TimeStretchDialog : public ArdourDialog {
- ARDOUR::Session::TimeStretchRequest request;
+ ARDOUR::TimeStretchRequest request;
Editor& editor;
RegionSelection regions;
Gtk::ProgressBar progress_bar;
@@ -2001,6 +2000,16 @@ class Editor : public PublicEditor
void history_changed ();
Gtk::HBox status_bar_hpacker;
+
+ Editing::EditPoint _edit_point;
+
+ Gtk::ComboBoxText edit_point_selector;
+
+ void set_edit_point (Editing::EditPoint ep);
+ void edit_point_selection_done ();
+ void edit_point_chosen (Editing::EditPoint);
+ Glib::RefPtr<Gtk::RadioAction> edit_point_action (Editing::EditPoint);
+ std::vector<std::string> edit_point_strings;
};
#endif /* __ardour_editor_h__ */
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index db81531583..b68f4bf2b7 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -291,6 +291,8 @@ Editor::register_actions ()
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_radio_action (zoom_actions, zoom_group, "zoom-focus-playhead", _("Zoom Focus Playhead"), bind (mem_fun(*this, &Editor::zoom_focus_chosen), Editing::ZoomFocusPlayhead));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::register_radio_action (zoom_actions, zoom_group, "zoom-focus-mouse", _("Zoom Focus Mouse"), bind (mem_fun(*this, &Editor::zoom_focus_chosen), Editing::ZoomFocusMouse));
+ ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_radio_action (zoom_actions, zoom_group, "zoom-focus-edit", _("Zoom Focus Edit"), bind (mem_fun(*this, &Editor::zoom_focus_chosen), Editing::ZoomFocusEdit));
ActionManager::session_sensitive_actions.push_back (act);
@@ -304,6 +306,11 @@ Editor::register_actions ()
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Timefx Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseTimeFX, false));
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-note", _("Note Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseNote, false));
+ RadioAction::Group edit_point_group;
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-playhead"), _("Playhead"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-mouse"), _("Mouse"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-selected-marker"), _("Marker"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+
ActionManager::register_action (editor_actions, X_("SnapTo"), _("Snap To"));
ActionManager::register_action (editor_actions, X_("SnapMode"), _("Snap Mode"));
@@ -829,6 +836,54 @@ Editor::snap_mode_chosen (SnapMode mode)
}
}
+RefPtr<RadioAction>
+Editor::edit_point_action (EditPoint ep)
+{
+ const char* action = 0;
+ RefPtr<Action> act;
+
+ switch (ep) {
+ case Editing::EditAtPlayhead:
+ action = X_("edit-at-playhead");
+ break;
+ case Editing::EditAtSelectedMarker:
+ action = X_("edit-at-selected-marker");
+ break;
+ case Editing::EditAtMouse:
+ action = X_("edit-at-mouse");
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible edit point type", (int) ep) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ return ract;
+
+ } else {
+ error << string_compose (_("programming error: %1: %2"), "Editor::edit_point_action could not find action to match edit point.", action) << endmsg;
+ return RefPtr<RadioAction> ();
+ }
+}
+
+void
+Editor::edit_point_chosen (EditPoint ep)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<RadioAction> ract = edit_point_action (ep);
+
+ if (ract && ract->get_active()) {
+ set_edit_point (ep);
+ }
+}
+
RefPtr<RadioAction>
Editor::zoom_focus_action (ZoomFocus focus)
@@ -849,6 +904,9 @@ Editor::zoom_focus_action (ZoomFocus focus)
case ZoomFocusPlayhead:
action = X_("zoom-focus-playhead");
break;
+ case ZoomFocusMouse:
+ action = X_("zoom-focus-mouse");
+ break;
case ZoomFocusEdit:
action = X_("zoom-focus-edit");
break;
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 0dc0d707c0..b609918f09 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -144,7 +144,7 @@ Editor::external_audio_dialog ()
switch (pos) {
case ImportAtEditCursor:
- where = edit_cursor->current_frame;
+ where = get_preferred_edit_position ();
break;
case ImportAtTimestamp:
where = -1;
@@ -157,6 +157,10 @@ Editor::external_audio_dialog ()
break;
}
+ if (where < 0) {
+ return;
+ }
+
SrcQuality quality = sfbrowser->get_src_quality();
if (sfbrowser->copy_files_btn.get_active()) {
@@ -591,7 +595,7 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
pos = sources[0]->natural_position();
} else {
// XXX is this the best alternative ?
- pos = edit_cursor->current_frame;
+ pos = get_preferred_edit_position ();
}
}
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 394d35e245..a22edea7e0 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -202,7 +202,6 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
default:
break;
}
-
return ret;
}
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index 724ff2c31a..50bf950054 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -188,9 +188,9 @@ Editor::LocationMarkers::~LocationMarkers ()
}
Editor::LocationMarkers *
-Editor::find_location_markers (Location *location)
+Editor::find_location_markers (Location *location) const
{
- LocationMarkerMap::iterator i;
+ LocationMarkerMap::const_iterator i;
for (i = location_markers.begin(); i != location_markers.end(); ++i) {
if ((*i).first == location) {
@@ -202,9 +202,9 @@ Editor::find_location_markers (Location *location)
}
Location *
-Editor::find_location_from_marker (Marker *marker, bool& is_start)
+Editor::find_location_from_marker (Marker *marker, bool& is_start) const
{
- LocationMarkerMap::iterator i;
+ LocationMarkerMap::const_iterator i;
for (i = location_markers.begin(); i != location_markers.end(); ++i) {
LocationMarkers *lm = (*i).second;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 8efce4daac..7857082be3 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -76,8 +76,46 @@ using namespace Editing;
const static double ZERO_GAIN_FRACTION = gain_to_slider_position(dB_to_coefficient(0.0));
-nframes_t
-Editor::event_frame (GdkEvent* event, double* pcx, double* pcy)
+bool
+Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const
+{
+ int x, y;
+ double wx, wy;
+ Gdk::ModifierType mask;
+ Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas.get_window();
+ Glib::RefPtr<const Gdk::Window> pointer_window;
+
+ pointer_window = canvas_window->get_pointer (x, y, mask);
+
+ if (pointer_window == track_canvas.get_bin_window()) {
+
+ track_canvas.window_to_world (x, y, wx, wy);
+ in_track_canvas = true;
+
+ } else {
+ in_track_canvas = false;
+
+ if (pointer_window == time_canvas.get_bin_window()) {
+ time_canvas.window_to_world (x, y, wx, wy);
+ } else {
+ return false;
+ }
+ }
+
+ wx += horizontal_adjustment.get_value();
+ wy += vertical_adjustment.get_value();
+
+ GdkEvent event;
+ event.type = GDK_BUTTON_RELEASE;
+ event.button.x = wx;
+ event.button.y = wy;
+
+ where = event_frame (&event, 0, 0);
+ return true;
+}
+
+nframes64_t
+Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const
{
double cx, cy;
@@ -773,10 +811,8 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
case MouseAudition:
_scrubbing = true;
- last_scrub_frame = 0;
- last_scrub_time = 0;
- have_full_mouse_speed = false;
- memset (mouse_speed, 0, sizeof (double) * mouse_speed_size);
+ last_scrub_x = event->button.x;
+ scrubbing_direction = 0;
/* rest handled in motion & release */
break;
@@ -1110,7 +1146,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case MouseAudition:
_scrubbing = false;
- if (last_scrub_frame == 0) {
+ if (scrubbing_direction == 0) {
/* no drag, just a click */
switch (item_type) {
case RegionItem:
@@ -1467,12 +1503,6 @@ Editor::left_automation_track ()
return false;
}
-static gboolean
-_update_mouse_speed (void *arg)
-{
- return static_cast<Editor*>(arg)->update_mouse_speed ();
-}
-
bool
Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type, bool from_autoscroll)
{
@@ -1509,56 +1539,53 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
switch (mouse_mode) {
case MouseAudition:
if (_scrubbing) {
- struct timeval tmnow;
-
- if (last_scrub_frame == 0) {
- /* first motion, just set up the variables */
+ double delta;
- last_scrub_frame = (nframes64_t) drag_info.current_pointer_frame;
- gettimeofday (&tmnow, 0);
- last_scrub_time = tmnow.tv_sec * 1000000.0 + tmnow.tv_usec;
- session->request_locate (last_scrub_frame, true);
+ if (scrubbing_direction == 0) {
+ /* first move */
+ session->request_locate (drag_info.current_pointer_frame, false);
+ session->request_transport_speed (0.1);
+ scrubbing_direction = 1;
} else {
- /* how fast is the mouse moving ? */
-
- double speed;
- nframes_t distance;
- double time;
- double dir;
-#if 1
- if (last_scrub_frame < (nframes64_t) drag_info.current_pointer_frame) {
- distance = (nframes64_t) drag_info.current_pointer_frame - last_scrub_frame;
- dir = 1.0;
- } else {
- distance = last_scrub_frame - (nframes64_t) drag_info.current_pointer_frame;
- dir = -1.0;
- }
-#else
- if (drag_info.grab_x < drag_info.current_pointer_x) {
- distance = drag_info.current_pointer_x - drag_info.grab_x;
- dir = -1.0;
+
+ if (last_scrub_x > drag_info.current_pointer_x) {
+ /* move to the left */
+
+ if (scrubbing_direction > 0) {
+ /* we reversed direction to go backwards */
+
+ session->request_transport_speed (-0.1);
+
+ } else {
+ /* still moving to the left (backwards) */
+
+ delta = 0.005 * (last_scrub_x - drag_info.current_pointer_x);
+ session->request_transport_speed (session->transport_speed() - delta);
+ }
+
+ scrubbing_direction = -1;
+
} else {
- distance = drag_info.grab_x - drag_info.current_pointer_x;
- dir = 1.0;
- }
-#endif
-
- gettimeofday (&tmnow, 0);
- time = (tmnow.tv_sec * 1000000.0 + tmnow.tv_usec) - last_scrub_time;
- last_scrub_frame = drag_info.current_pointer_frame;
- last_scrub_time = (tmnow.tv_sec * 1000000.0) + tmnow.tv_usec;
- speed = ((double)distance/session->frame_rate()) / (time/1000000.0); // frames/sec
-
- add_mouse_speed (speed, dir);
-
- if (mouse_speed_update < 0) {
- mouse_speed_update = g_timeout_add (10, _update_mouse_speed, this);
- update_mouse_speed ();
+ /* move to the right */
+ if (scrubbing_direction < 0) {
+ /* we reversed direction to go forward */
+
+ session->request_transport_speed (0.1);
+ } else {
+ /* still moving to the right */
+
+ delta = 0.005 * (drag_info.current_pointer_x - last_scrub_x);
+ session->request_transport_speed (session->transport_speed() + delta);
+ }
+
+ scrubbing_direction = 1;
}
}
+
+ last_scrub_x = drag_info.current_pointer_x;
}
default:
@@ -2607,8 +2634,7 @@ Editor::start_control_point_grab (ArdourCanvas::Item* item, GdkEvent* event)
drag_info.grab_x = control_point->get_x();
drag_info.grab_y = control_point->get_y();
control_point->line().parent_group().i2w(drag_info.grab_x, drag_info.grab_y);
- track_canvas.w2c(drag_info.grab_x, drag_info.grab_y,
- drag_info.grab_x, drag_info.grab_y);
+ track_canvas.w2c(drag_info.grab_x, drag_info.grab_y, drag_info.grab_x, drag_info.grab_y);
drag_info.grab_frame = pixel_to_frame(drag_info.grab_x);
@@ -3757,12 +3783,13 @@ Editor::create_region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent
snap_to (start, -1);
const Meter& m = session->tempo_map().meter_at(start);
const Tempo& t = session->tempo_map().tempo_at(start);
- double length = m.frames_per_bar(t, session->frame_rate());
+ double length = floor (m.frames_per_bar(t, session->frame_rate()));
boost::shared_ptr<Source> src = session->create_midi_source_for_session(*diskstream.get());
- mtv->playlist()->add_region (boost::dynamic_pointer_cast<MidiRegion>(RegionFactory::create(
- src, 0, length, PBD::basename_nosuffix(src->name()))), start);
+ mtv->playlist()->add_region (boost::dynamic_pointer_cast<MidiRegion>
+ (RegionFactory::create(src, 0, (nframes_t) length,
+ PBD::basename_nosuffix(src->name()))), start);
XMLNode &after = mtv->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*mtv->playlist().get(), &before, &after));
commit_reversible_command();
@@ -3788,17 +3815,22 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
speed = rtv->get_diskstream()->speed();
}
- if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
-
- align_region (rv.region(), SyncPoint, (nframes_t) (edit_cursor->current_frame * speed));
-
- } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
+ nframes64_t where = get_preferred_edit_position();
- align_region (rv.region(), End, (nframes_t) (edit_cursor->current_frame * speed));
+ if (where >= 0) {
- } else {
-
- align_region (rv.region(), Start, (nframes_t) (edit_cursor->current_frame * speed));
+ if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
+
+ align_region (rv.region(), SyncPoint, (nframes_t) (where * speed));
+
+ } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
+
+ align_region (rv.region(), End, (nframes_t) (where * speed));
+
+ } else {
+
+ align_region (rv.region(), Start, (nframes_t) (where * speed));
+ }
}
}
}
@@ -5197,90 +5229,3 @@ Editor::track_height_step_timeout ()
return true;
}
-
-void
-Editor::add_mouse_speed (double speed, double dir)
-{
- size_t index;
-
- mouse_direction = dir;
-
- index = mouse_speed_entries;
-
- if (++index >= mouse_speed_size) {
- index = 0;
- have_full_mouse_speed = true;
- }
-
- mouse_speed[index] = speed;
- mouse_speed_entries = index;
-}
-
-double
-Editor::compute_mouse_speed ()
-{
- double total = 0;
-
- if (!have_full_mouse_speed) {
-
- /* partial speed buffer, just use whatever we have so far */
-
- if (mouse_speed_entries == 0 ) {
- return 0.0;
- }
-
- for (size_t n = 0; n < mouse_speed_entries; ++n) {
- total += mouse_speed[n];
- }
-
- return mouse_direction * total/mouse_speed_entries;
- }
-
- /* compute the average (effectively low-pass filtering) mouse speed
- across the entire buffer.
- */
-
- for (size_t n = 0; n < mouse_speed_size; ++n) {
- total += mouse_speed[n];
- }
-
-
- return mouse_direction * total/mouse_speed_size;
-}
-
-bool
-Editor::update_mouse_speed ()
-{
- double speed;
-
- if (!_scrubbing) {
- session->request_transport_speed (0.0);
- mouse_speed_update = -1;
- return false;
- }
-
- speed = compute_mouse_speed ();
-
- struct timeval tmnow;
-
- gettimeofday (&tmnow, 0);
- double now = (tmnow.tv_sec * 1000000.0) + tmnow.tv_usec;
-
- if (now - last_scrub_time > 250000) {
-
- // 0.25 seconds since last mouse motion, start to brake
-
- if (fabs (speed) < 0.1) {
- /* don't asymptotically approach zero */
- memset (mouse_speed, 0, sizeof (double) * mouse_speed_size);
- speed = 0.0;
- } else if (fabs (speed) < 0.25) {
- add_mouse_speed (fabs (speed * 0.2), mouse_direction);
- } else {
- add_mouse_speed (fabs (speed * 0.6), mouse_direction);
- }
- }
-
- session->request_transport_speed (speed);
- return _scrubbing;
-}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 2cc30aee17..7ae7706928 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -95,17 +95,10 @@ Editor::redo (uint32_t n)
}
}
-int
-Editor::ensure_cursor (nframes_t *pos)
-{
- *pos = edit_cursor->current_frame;
- return 0;
-}
-
void
Editor::split_region ()
{
- split_region_at (edit_cursor->current_frame);
+ split_region_at (get_preferred_edit_position());
}
void
@@ -137,8 +130,21 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
snap_to (where);
}
+ for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
- for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ++a) {
+ RegionSelection::iterator tmp;
+
+ /* XXX this test needs to be more complicated, to make sure we really
+ have something to split.
+ */
+
+ if (!(*a)->region()->covers (where)) {
+ ++a;
+ continue;
+ }
+
+ tmp = a;
+ ++tmp;
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
@@ -161,6 +167,7 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
+ a = tmp;
}
while (used_playlists.size() > 0) {
@@ -883,7 +890,7 @@ Editor::cursor_align (bool playhead_to_edit)
{
if (playhead_to_edit) {
if (session) {
- session->request_locate (edit_cursor->current_frame);
+ session->request_locate (get_preferred_edit_position());
}
} else {
edit_cursor->set_position (playhead_cursor->current_frame);
@@ -893,8 +900,8 @@ Editor::cursor_align (bool playhead_to_edit)
void
Editor::edit_cursor_backward ()
{
- nframes_t pos;
- nframes_t cnt;
+ nframes64_t pos;
+ nframes64_t cnt;
float prefix;
bool was_floating;
@@ -908,9 +915,11 @@ Editor::edit_cursor_backward ()
}
}
- pos = edit_cursor->current_frame;
+ if ((pos = get_preferred_edit_position()) < 0) {
+ return;
+ }
- if ((nframes_t) pos < cnt) {
+ if (pos < cnt) {
pos = 0;
} else {
pos -= cnt;
@@ -1099,12 +1108,14 @@ Editor::temporal_zoom (gdouble fpu)
{
if (!session) return;
- nframes_t current_page = current_page_frames();
- nframes_t current_leftmost = leftmost_frame;
- nframes_t current_rightmost;
- nframes_t current_center;
- nframes_t new_page;
- nframes_t leftmost_after_zoom = 0;
+ nframes64_t current_page = current_page_frames();
+ nframes64_t current_leftmost = leftmost_frame;
+ nframes64_t current_rightmost;
+ nframes64_t current_center;
+ nframes64_t new_page;
+ nframes64_t leftmost_after_zoom = 0;
+ nframes64_t where;
+ bool in_track_canvas;
double nfpu;
nfpu = fpu;
@@ -1143,10 +1154,38 @@ Editor::temporal_zoom (gdouble fpu)
}
break;
+ case ZoomFocusMouse:
+ /* try to keep the mouse over the same point in the display */
+
+ if (!mouse_frame (where, in_track_canvas)) {
+ /* use playhead instead */
+ where = playhead_cursor->current_frame;
+
+ if (where > new_page/2) {
+ leftmost_after_zoom = where - (new_page/2);
+ } else {
+ leftmost_after_zoom = 0;
+ }
+
+ } else {
+
+ double l = - ((new_page * ((where - current_leftmost)/(double)current_page)) - where);
+
+ if (l < 0) {
+ leftmost_after_zoom = 0;
+ } else if (l > max_frames) {
+ leftmost_after_zoom = max_frames - new_page;
+ } else {
+ leftmost_after_zoom = (nframes64_t) l;
+ }
+ }
+
+ break;
+
case ZoomFocusEdit:
/* try to keep the edit cursor in the center */
- if (edit_cursor->current_frame > new_page/2) {
- leftmost_after_zoom = edit_cursor->current_frame - (new_page/2);
+ if (get_preferred_edit_position() > new_page/2) {
+ leftmost_after_zoom = get_preferred_edit_position() - (new_page/2);
} else {
leftmost_after_zoom = 0;
}
@@ -1160,6 +1199,8 @@ Editor::temporal_zoom (gdouble fpu)
// session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), current_leftmost, frames_per_unit));
// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_after_zoom, nfpu));
// commit_reversible_command ();
+
+ // cerr << "repos & zoom to " << leftmost_after_zoom << " @ " << nfpu << endl;
reposition_and_zoom (leftmost_after_zoom, nfpu);
}
@@ -1579,7 +1620,7 @@ Editor::insert_region_list_selection (float times)
begin_reversible_command (_("insert region"));
XMLNode &before = playlist->get_state();
- playlist->add_region ((RegionFactory::create (region)), edit_cursor->current_frame, times);
+ playlist->add_region ((RegionFactory::create (region)), get_preferred_edit_position(), times);
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
}
@@ -1666,7 +1707,7 @@ Editor::play_from_start ()
void
Editor::play_from_edit_cursor ()
{
- session->request_locate (edit_cursor->current_frame, true);
+ session->request_locate (get_preferred_edit_position(), true);
}
void
@@ -2275,7 +2316,8 @@ Editor::set_region_sync_from_edit_cursor ()
{
/* Check that at the edit cursor is in at least one of the selected regions */
RegionSelection::const_iterator i = selection->regions.begin();
- while (i != selection->regions.end() && !(*i)->region()->covers (edit_cursor->current_frame)) {
+
+ while (i != selection->regions.end() && !(*i)->region()->covers (get_preferred_edit_position())) {
++i;
}
@@ -2290,11 +2332,11 @@ Editor::set_region_sync_from_edit_cursor ()
for (RegionSelection::iterator j = selection->regions.begin(); j != selection->regions.end(); ++j) {
boost::shared_ptr<Region> r = (*j)->region();
XMLNode &before = r->playlist()->get_state();
- r->set_sync_position (edit_cursor->current_frame);
+ r->set_sync_position (get_preferred_edit_position());
XMLNode &after = r->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
}
-
+
commit_reversible_command ();
}
@@ -2334,13 +2376,13 @@ Editor::naturalize ()
void
Editor::align (RegionPoint what)
{
- align_selection (what, edit_cursor->current_frame);
+ align_selection (what, get_preferred_edit_position());
}
void
Editor::align_relative (RegionPoint what)
{
- align_selection_relative (what, edit_cursor->current_frame);
+ align_selection_relative (what, get_preferred_edit_position());
}
struct RegionSortByTime {
@@ -2481,7 +2523,7 @@ Editor::trim_region_to_edit_cursor ()
}
XMLNode &before = region->playlist()->get_state();
- region->trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
+ region->trim_end( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
XMLNode &after = region->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
}
@@ -2513,12 +2555,10 @@ Editor::trim_region_from_edit_cursor ()
}
XMLNode &before = region->playlist()->get_state();
- region->trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
+ region->trim_front ( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
XMLNode &after = region->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
}
-
- commit_reversible_command ();
}
/** Unfreeze selected routes */
@@ -2945,26 +2985,19 @@ Editor::cut_copy_ranges (CutCopyOp op)
void
Editor::paste (float times)
{
- paste_internal (edit_cursor->current_frame, times);
+ paste_internal (get_preferred_edit_position(), times);
}
void
Editor::mouse_paste ()
{
- int x, y;
- double wx, wy;
+ nframes64_t where;
+ bool ignored;
- track_canvas.get_pointer (x, y);
- track_canvas.window_to_world (x, y, wx, wy);
- wx += horizontal_adjustment.get_value();
- wy += vertical_adjustment.get_value();
+ if (!mouse_frame (where, ignored)) {
+ return;
+ }
- GdkEvent event;
- event.type = GDK_BUTTON_RELEASE;
- event.button.x = wx;
- event.button.y = wy;
-
- nframes_t where = event_frame (&event, 0, 0);
snap_to (where);
paste_internal (where, 1);
}
@@ -2979,7 +3012,7 @@ Editor::paste_internal (nframes_t position, float times)
}
if (position == max_frames) {
- position = edit_cursor->current_frame;
+ position = get_preferred_edit_position();
}
begin_reversible_command (_("paste"));
@@ -3050,7 +3083,7 @@ Editor::paste_named_selection (float times)
++tmp;
XMLNode &before = apl->get_state();
- apl->paste (*chunk, edit_cursor->current_frame, times);
+ apl->paste (*chunk, get_preferred_edit_position(), times);
session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
if (tmp != ns->playlists.end()) {
@@ -3162,7 +3195,7 @@ Editor::center_edit_cursor ()
{
float page = canvas_width * frames_per_unit;
- center_screen_internal (edit_cursor->current_frame, page);
+ center_screen_internal (get_preferred_edit_position(), page);
}
void
@@ -3185,7 +3218,7 @@ Editor::nudge_selected_tracks (bool use_edit_cursor, bool forwards)
nframes_t start;
if (use_edit_cursor) {
- start = edit_cursor->current_frame;
+ start = get_preferred_edit_position();
} else {
start = 0;
}
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index 910534690e..12ca558ea4 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -616,16 +616,10 @@ Editor::track_selection_changed ()
}
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- (*i)->set_selected (false);
- if (mouse_mode == MouseRange) {
- (*i)->hide_selection ();
- }
- }
-
- for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
- (*i)->set_selected (true);
- if (mouse_mode == MouseRange) {
- (*i)->show_selection (selection->time);
+ if (find (selection->tracks.begin(), selection->tracks.end(), *i) != selection->tracks.end()) {
+ (*i)->set_selected (true);
+ } else {
+ (*i)->set_selected (false);
}
}
}
@@ -652,6 +646,7 @@ Editor::time_selection_changed ()
} else {
ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, true);
}
+
}
void
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index 2efdc03f8f..df0a73c965 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -39,6 +39,7 @@
#include <ardour/audio_track.h>
#include <ardour/audioregion.h>
#include <ardour/audio_diskstream.h>
+#include <ardour/stretch.h>
#include "i18n.h"
@@ -87,29 +88,29 @@ gint
Editor::TimeStretchDialog::update_progress ()
{
progress_bar.set_fraction (request.progress);
- return request.running;
+ return !request.done;
}
void
Editor::TimeStretchDialog::cancel_timestretch_in_progress ()
{
status = -2;
- request.running = false;
+ request.cancel = true;
+ first_cancel.disconnect();
}
gint
Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev)
{
status = -2;
- request.running = false;
+ request.cancel = true;
+ first_delete.disconnect();
return TRUE;
}
int
Editor::run_timestretch (RegionSelection& regions, float fraction)
{
- pthread_t thread;
-
if (current_timestretch == 0) {
current_timestretch = new TimeStretchDialog (*this);
}
@@ -130,27 +131,30 @@ Editor::run_timestretch (RegionSelection& regions, float fraction)
current_timestretch->request.quick_seek = current_timestretch->quick_button.get_active();
current_timestretch->request.antialias = !current_timestretch->antialias_button.get_active();
current_timestretch->request.progress = 0.0f;
- current_timestretch->request.running = true;
+ current_timestretch->request.done = false;
+ current_timestretch->request.cancel = false;
/* re-connect the cancel button and delete events */
current_timestretch->first_cancel.disconnect();
current_timestretch->first_delete.disconnect();
- current_timestretch->cancel_button->signal_clicked().connect (mem_fun (current_timestretch, &TimeStretchDialog::cancel_timestretch_in_progress));
- current_timestretch->signal_delete_event().connect (mem_fun (current_timestretch, &TimeStretchDialog::delete_timestretch_in_progress));
+ current_timestretch->first_cancel = current_timestretch->cancel_button->signal_clicked().connect
+ (mem_fun (current_timestretch, &TimeStretchDialog::cancel_timestretch_in_progress));
+ current_timestretch->first_delete = current_timestretch->signal_delete_event().connect
+ (mem_fun (current_timestretch, &TimeStretchDialog::delete_timestretch_in_progress));
- if (pthread_create_and_store ("timestretch", &thread, 0, timestretch_thread, current_timestretch)) {
+ if (pthread_create_and_store ("timestretch", &current_timestretch->request.thread, 0, timestretch_thread, current_timestretch)) {
current_timestretch->hide ();
error << _("timestretch cannot be started - thread creation error") << endmsg;
return -1;
}
- pthread_detach (thread);
+ pthread_detach (current_timestretch->request.thread);
sigc::connection c = Glib::signal_timeout().connect (mem_fun (current_timestretch, &TimeStretchDialog::update_progress), 100);
- while (current_timestretch->request.running) {
+ while (!current_timestretch->request.done) {
gtk_main_iteration ();
}
@@ -195,31 +199,34 @@ Editor::do_timestretch (TimeStretchDialog& dialog)
continue;
}
- dialog.request.region = region;
-
- if (!dialog.request.running) {
+ if (dialog.request.cancel) {
/* we were cancelled */
dialog.status = 1;
return;
}
- if ((new_region = session->tempoize_region (dialog.request)) == 0) {
+ Stretch stretch (*session, dialog.request);
+
+ if (stretch.run (region)) {
dialog.status = -1;
- dialog.request.running = false;
+ dialog.request.done = true;
return;
}
- XMLNode &before = playlist->get_state();
- playlist->replace_region (region, new_region, region->position());
- XMLNode &after = playlist->get_state();
- session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+ if (!stretch.results.empty()) {
+ new_region = stretch.results.front();
+
+ XMLNode &before = playlist->get_state();
+ playlist->replace_region (region, new_region, region->position());
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+ }
i = tmp;
}
dialog.status = 0;
- dialog.request.running = false;
- dialog.request.region.reset ();
+ dialog.request.done = true;
}
void*
diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc
index c33b2965c3..f626bfb968 100644
--- a/gtk2_ardour/enums.cc
+++ b/gtk2_ardour/enums.cc
@@ -38,6 +38,7 @@ setup_gtk_ardour_enums ()
AudioClock::Mode clock_mode;
Width width;
ImportMode import_mode;
+ EditPoint edit_point;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@@ -60,4 +61,9 @@ setup_gtk_ardour_enums ()
REGISTER_ENUM (ImportAsRegion);
REGISTER_ENUM (ImportAsTapeTrack);
REGISTER (import_mode);
+
+ REGISTER_ENUM (EditAtPlayhead);
+ REGISTER_ENUM (EditAtMouse);
+ REGISTER_ENUM (EditAtSelectedMarker);
+ REGISTER (edit_point);
}
diff --git a/gtk2_ardour/marker_selection.h b/gtk2_ardour/marker_selection.h
new file mode 100644
index 0000000000..aa1413ed3e
--- /dev/null
+++ b/gtk2_ardour/marker_selection.h
@@ -0,0 +1,31 @@
+/*
+ Copyright (C) 2000-2007 Paul Davis
+
+ 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.
+
+*/
+
+#ifndef __ardour_gtk_marker_selection_h__
+#define __ardour_gtk_marker_selection_h__
+
+#include <list>
+
+#include "marker.h"
+
+struct MarkerSelection : public std::list<Marker*>
+{
+};
+
+#endif /* __ardour_gtk_marker_selection_h__ */
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 03d5897c1a..f32c0565e3 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -185,11 +185,11 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual void toggle_playback (bool with_abort) = 0;
virtual void transition_to_rolling (bool fwd) = 0;
- virtual nframes_t unit_to_frame (double unit) = 0;
- virtual double frame_to_unit (nframes_t frame) = 0;
- virtual double frame_to_unit (double frame) = 0;
- virtual nframes_t pixel_to_frame (double pixel) = 0;
- virtual gulong frame_to_pixel (nframes_t frame) = 0;
+ virtual nframes_t unit_to_frame (double unit) const = 0;
+ virtual double frame_to_unit (nframes_t frame) const = 0;
+ virtual double frame_to_unit (double frame) const = 0;
+ virtual nframes64_t pixel_to_frame (double pixel) const = 0;
+ virtual gulong frame_to_pixel (nframes64_t frame) const = 0;
virtual Selection& get_selection () const = 0;
virtual Selection& get_cut_buffer () const = 0;
virtual bool extend_selection_to_track (TimeAxisView&) = 0;
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index f0037588a0..c6bb5c37af 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -144,6 +144,15 @@ Selection::clear_lines ()
}
void
+Selection::clear_markers ()
+{
+ if (!markers.empty()) {
+ markers.clear ();
+ MarkersChanged();
+ }
+}
+
+void
Selection::toggle (boost::shared_ptr<Playlist> pl)
{
PlaylistSelection::iterator i;
@@ -575,7 +584,8 @@ Selection::empty ()
playlists.empty () &&
lines.empty () &&
time.empty () &&
- playlists.empty ()
+ playlists.empty () &&
+ markers.empty()
;
}
@@ -700,3 +710,43 @@ Selection::select_edit_group_regions ()
add (*i);
}
}
+
+void
+Selection::set (Marker* m)
+{
+ clear_markers ();
+ add (m);
+}
+
+void
+Selection::toggle (Marker* m)
+{
+ MarkerSelection::iterator i;
+
+ if ((i = find (markers.begin(), markers.end(), m)) == markers.end()) {
+ add (m);
+ } else {
+ remove (m);
+ }
+}
+
+void
+Selection::remove (Marker* m)
+{
+ MarkerSelection::iterator i;
+
+ if ((i = find (markers.begin(), markers.end(), m)) != markers.end()) {
+ markers.erase (i);
+ MarkersChanged();
+ }
+}
+
+
+void
+Selection::add (Marker* m)
+{
+ if (find (markers.begin(), markers.end(), m) == markers.end()) {
+ markers.push_back (m);
+ MarkersChanged();
+ }
+}
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index 5e9bc04759..2b2db77360 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -32,6 +32,7 @@
#include "playlist_selection.h"
#include "processor_selection.h"
#include "point_selection.h"
+#include "marker_selection.h"
class TimeAxisView;
class RegionView;
@@ -71,6 +72,7 @@ class Selection : public sigc::trackable
AutomationSelection lines;
PlaylistSelection playlists;
PointSelection points;
+ MarkerSelection markers;
Selection (PublicEditor const * e) : editor (e), next_time_id (0) {
clear();
@@ -84,6 +86,7 @@ class Selection : public sigc::trackable
sigc::signal<void> LinesChanged;
sigc::signal<void> PlaylistsChanged;
sigc::signal<void> PointsChanged;
+ sigc::signal<void> MarkersChanged;
void clear ();
bool empty();
@@ -106,6 +109,7 @@ class Selection : public sigc::trackable
void set (boost::shared_ptr<ARDOUR::Playlist>);
void set (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void set (AutomationSelectable*);
+ void set (Marker*);
void toggle (TimeAxisView*);
void toggle (const std::list<TimeAxisView*>&);
@@ -116,6 +120,7 @@ class Selection : public sigc::trackable
void toggle (boost::shared_ptr<ARDOUR::Playlist>);
void toggle (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void toggle (const std::vector<AutomationSelectable*>&);
+ void toggle (Marker*);
void add (TimeAxisView*);
void add (const std::list<TimeAxisView*>&);
@@ -125,7 +130,8 @@ class Selection : public sigc::trackable
void add (ARDOUR::AutomationList*);
void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
-
+ void add (Marker*);
+
void remove (TimeAxisView*);
void remove (const std::list<TimeAxisView*>&);
void remove (RegionView*);
@@ -135,6 +141,7 @@ class Selection : public sigc::trackable
void remove (boost::shared_ptr<ARDOUR::Playlist>);
void remove (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (const list<Selectable*>&);
+ void remove (Marker*);
void replace (uint32_t time_index, nframes_t start, nframes_t end);
@@ -144,6 +151,7 @@ class Selection : public sigc::trackable
void clear_lines ();
void clear_playlists ();
void clear_points ();
+ void clear_markers ();
void foreach_region (void (ARDOUR::Region::*method)(void));
void foreach_regionview (void (RegionView::*method)(void));
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index 4d2533ebff..cf0e39cdbd 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -545,12 +545,16 @@ TimeAxisView::popup_size_menu (guint32 when)
void
TimeAxisView::set_selected (bool yn)
{
- AxisView::set_selected (yn);
+ if (yn == _selected) {
+ return;
+ }
+
+ Selectable::set_selected (yn);
if (_selected) {
controls_ebox.set_name (controls_base_selected_name);
controls_frame.set_name (controls_base_selected_name);
-
+
/* propagate any existing selection, if the mode is right */
if (editor.current_mouse_mode() == Editing::MouseRange && !editor.get_selection().time.empty()) {
@@ -571,8 +575,6 @@ TimeAxisView::set_selected (bool yn)
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
(*i)->set_selected (false);
}
-
-
}
}
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index 570a481c11..941132396a 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -22,6 +22,7 @@
#include <fstream>
#include <sys/stat.h>
#include <libart_lgpl/art_misc.h>
+#include <gtkmm/rc.h>
#include <gtkmm/window.h>
#include <gtkmm/combo.h>
#include <gtkmm/label.h>
@@ -325,6 +326,61 @@ rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, s
}
}
+
+Gdk::Color
+color_from_style (string widget_style_name, int state, string attr)
+{
+ GtkStyle* style;
+
+ style = gtk_rc_get_style_by_paths (gtk_settings_get_default(),
+ widget_style_name.c_str(),
+ 0, G_TYPE_NONE);
+
+ if (!style) {
+ error << string_compose (_("no style found for %1, using red"), style) << endmsg;
+ return Gdk::Color ("red");
+ }
+
+ cerr << "got style for " << widget_style_name << endl;
+
+ if (attr == "fg") {
+ return Gdk::Color (&style->fg[state]);
+ }
+
+ if (attr == "bg") {
+ cerr << "returning color from bg\n";
+ return Gdk::Color (&style->bg[state]);
+ }
+
+ if (attr == "light") {
+ return Gdk::Color (&style->light[state]);
+ }
+
+ if (attr == "dark") {
+ return Gdk::Color (&style->dark[state]);
+ }
+
+ if (attr == "mid") {
+ return Gdk::Color (&style->mid[state]);
+ }
+
+ if (attr == "text") {
+ return Gdk::Color (&style->text[state]);
+ }
+
+ if (attr == "base") {
+ return Gdk::Color (&style->base[state]);
+ }
+
+ if (attr == "text_aa") {
+ return Gdk::Color (&style->text_aa[state]);
+ }
+
+ error << string_compose (_("unknown style attribute %1 requested for color; using \"red\""), attr) << endmsg;
+ return Gdk::Color ("red");
+}
+
+
bool
canvas_item_visible (ArdourCanvas::Item* item)
{
diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h
index cae78f3d0a..74a6eebd21 100644
--- a/gtk2_ardour/utils.h
+++ b/gtk2_ardour/utils.h
@@ -67,6 +67,8 @@ Pango::FontDescription* get_font_for_style (std::string widgetname);
uint32_t rgba_from_style (std::string, uint32_t, uint32_t, uint32_t, uint32_t, std::string = "fg", int = Gtk::STATE_NORMAL, bool = true);
+Gdk::Color color_from_style (std::string widget_style_name, int state, std::string attr);
+
void decorate (Gtk::Window& w, Gdk::WMDecoration d);
bool canvas_item_visible (ArdourCanvas::Item* item);