summaryrefslogtreecommitdiff
path: root/gtk2_ardour/editor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour/editor.cc')
-rw-r--r--gtk2_ardour/editor.cc566
1 files changed, 449 insertions, 117 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 3d14d96178..ab8940874c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -84,6 +84,7 @@
#include "gui_thread.h"
#include "simpleline.h"
#include "rhythm_ferret.h"
+#include "actions.h"
#ifdef FFT_ANALYSIS
#include "analysis_window.h"
@@ -266,6 +267,7 @@ Editor::Editor ()
clicked_control_point = 0;
last_update_frame = 0;
drag_info.item = 0;
+ drag_info.copied_location = 0;
current_mixer_strip = 0;
current_bbt_points = 0;
@@ -350,6 +352,13 @@ Editor::Editor ()
select_new_marker = false;
zoomed_to_region = false;
rhythm_ferret = 0;
+ allow_vertical_scroll = false;
+ no_save_visual = false;
+ need_resize_line = false;
+ resize_line_y = 0;
+ old_resize_line_y = -1;
+ no_region_list_redisplay = false;
+ resize_idle_id = -1;
_scrubbing = false;
scrubbing_direction = 0;
@@ -370,8 +379,6 @@ Editor::Editor ()
set_midi_edit_mode (MidiEditPencil, true);
set_mouse_mode (MouseObject, true);
- last_visual_state.frames_per_unit = 0;
-
frames_per_unit = 2048; /* too early to use reset_zoom () */
reset_hscrollbar_stepping ();
@@ -818,6 +825,7 @@ Editor::Editor ()
ControlProtocol::ZoomIn.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), false));
ControlProtocol::ZoomOut.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), true));
ControlProtocol::ScrollTimeline.connect (mem_fun (*this, &Editor::control_scroll));
+ BasicUI::AccessAction.connect (mem_fun (*this, &Editor::access_action));
Config->ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed));
Route::SyncOrderKeys.connect (mem_fun (*this, &Editor::sync_order_keys));
@@ -850,6 +858,16 @@ Editor::~Editor()
delete time_canvas;
time_canvas = 0;
}
+
+ if (track_canvas) {
+ delete track_canvas;
+ track_canvas = 0;
+ }
+
+ if (time_canvas) {
+ delete time_canvas;
+ time_canvas = 0;
+ }
}
void
@@ -971,10 +989,10 @@ Editor::zoom_adjustment_changed ()
if (fpu < 1.0) {
fpu = 1.0;
- zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+ zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
} else if (fpu > session->current_end_frame() / canvas_width) {
fpu = session->current_end_frame() / canvas_width;
- zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+ zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
}
temporal_zoom (fpu);
@@ -994,7 +1012,7 @@ Editor::control_scroll (float fraction)
/*
_control_scroll_target is an optional<T>
- it acts like a pointer to an nframes_t, with
+ it acts like a pointer to an nframes64_t, with
a operator conversion to boolean to check
that it has a value could possibly use
playhead_cursor->current_frame to store the
@@ -1007,12 +1025,12 @@ Editor::control_scroll (float fraction)
_dragging_playhead = true;
}
- if ((fraction < 0.0f) && (*_control_scroll_target < (nframes_t) fabs(step))) {
+ if ((fraction < 0.0f) && (*_control_scroll_target < (nframes64_t) fabs(step))) {
*_control_scroll_target = 0;
} else if ((fraction > 0.0f) && (max_frames - *_control_scroll_target < step)) {
*_control_scroll_target = max_frames - (current_page_frames()*2); // allow room for slop in where the PH is on the screen
} else {
- *_control_scroll_target += (nframes_t) floor (step);
+ *_control_scroll_target += (nframes64_t) floor (step);
}
/* move visuals, we'll catch up with it later */
@@ -1043,7 +1061,7 @@ Editor::control_scroll (float fraction)
}
bool
-Editor::deferred_control_scroll (nframes_t target)
+Editor::deferred_control_scroll (nframes64_t target)
{
session->request_locate (*_control_scroll_target, session->transport_rolling());
// reset for next stream
@@ -1053,6 +1071,27 @@ Editor::deferred_control_scroll (nframes_t target)
}
void
+Editor::access_action (std::string action_group, std::string action_item)
+{
+ if (!session) {
+ return;
+ }
+
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::access_action), action_group, action_item));
+
+ cout<< "OSC: Recieved: "<< action_item << endl;
+
+ RefPtr<Action> act;
+ act = ActionManager::get_action( action_group.c_str(), action_item.c_str() );
+
+ if (act) {
+ act->activate();
+ }
+
+
+}
+
+void
Editor::on_realize ()
{
Window::on_realize ();
@@ -1073,7 +1112,7 @@ Editor::stop_scrolling ()
}
void
-Editor::map_position_change (nframes_t frame)
+Editor::map_position_change (nframes64_t frame)
{
ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::map_position_change), frame));
@@ -1086,7 +1125,7 @@ Editor::map_position_change (nframes_t frame)
}
void
-Editor::center_screen (nframes_t frame)
+Editor::center_screen (nframes64_t frame)
{
double page = canvas_width * frames_per_unit;
@@ -1099,12 +1138,12 @@ Editor::center_screen (nframes_t frame)
}
void
-Editor::center_screen_internal (nframes_t frame, float page)
+Editor::center_screen_internal (nframes64_t frame, float page)
{
page /= 2;
if (frame > page) {
- frame -= (nframes_t) page;
+ frame -= (nframes64_t) page;
} else {
frame = 0;
}
@@ -1117,7 +1156,7 @@ Editor::handle_new_duration ()
{
ENSURE_GUI_THREAD (mem_fun (*this, &Editor::handle_new_duration));
- nframes_t new_end = session->get_maximum_extent() + (nframes_t) floorf (current_page_frames() * 0.10f);
+ nframes64_t new_end = session->get_maximum_extent() + (nframes64_t) floorf (current_page_frames() * 0.10f);
if (new_end > last_canvas_frame) {
last_canvas_frame = new_end;
@@ -1126,6 +1165,7 @@ Editor::handle_new_duration ()
}
horizontal_adjustment.set_value (leftmost_frame/frames_per_unit);
+ //cerr << "Editor::handle_new_duration () called ha v:l:u:ps:lcf = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << last_canvas_frame << endl;//DEBUG
}
void
@@ -1217,6 +1257,7 @@ Editor::connect_to_session (Session *t)
zoom_range_clock.set_session (session);
_playlist_selector->set_session (session);
nudge_clock.set_session (session);
+ nudge_clock.set (session->frame_rate() * 5); // default of 5 seconds
if (rhythm_ferret) {
rhythm_ferret->set_session (session);
@@ -1471,10 +1512,10 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
}
void
-Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes_t frame)
+Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes64_t frame)
{
using namespace Menu_Helpers;
- Menu* (Editor::*build_menu_function)(nframes_t);
+ Menu* (Editor::*build_menu_function)(nframes64_t);
Menu *menu;
switch (item_type) {
@@ -1590,7 +1631,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
}
Menu*
-Editor::build_track_context_menu (nframes_t ignored)
+Editor::build_track_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
@@ -1602,7 +1643,7 @@ Editor::build_track_context_menu (nframes_t ignored)
}
Menu*
-Editor::build_track_bus_context_menu (nframes_t ignored)
+Editor::build_track_bus_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
@@ -1614,7 +1655,7 @@ Editor::build_track_bus_context_menu (nframes_t ignored)
}
Menu*
-Editor::build_track_region_context_menu (nframes_t frame)
+Editor::build_track_region_context_menu (nframes64_t frame)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_region_context_menu.items();
@@ -1627,10 +1668,20 @@ Editor::build_track_region_context_menu (nframes_t frame)
boost::shared_ptr<Playlist> pl;
if ((ds = rtv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
- for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (rtv->view(), (*i), edit_items);
+ Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)frame * ds->speed()));
+
+ if (selection->regions.size() > 1) {
+ // there's already a multiple selection: just add a
+ // single region context menu that will act on all
+ // selected regions
+ boost::shared_ptr<Region> dummy_region; // = NULL
+ add_region_context_items (rtv->view(), dummy_region, edit_items);
+ } else {
+ for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+ add_region_context_items (rtv->view(), (*i), edit_items);
+ }
}
+
delete regions;
}
}
@@ -1641,7 +1692,7 @@ Editor::build_track_region_context_menu (nframes_t frame)
}
Menu*
-Editor::build_track_crossfade_context_menu (nframes_t frame)
+Editor::build_track_crossfade_context_menu (nframes64_t frame)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_crossfade_context_menu.items();
@@ -1667,10 +1718,17 @@ Editor::build_track_crossfade_context_menu (nframes_t frame)
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
}
- for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (atv->audio_view(), (*i), edit_items);
+ if (selection->regions.size() > 1) {
+ // there's already a multiple selection: just add a
+ // single region context menu that will act on all
+ // selected regions
+ boost::shared_ptr<Region> dummy_region; // = NULL
+ add_region_context_items (atv->audio_view(), dummy_region, edit_items);
+ } else {
+ for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+ add_region_context_items (atv->audio_view(), (*i), edit_items);
+ }
}
-
delete regions;
}
}
@@ -1719,7 +1777,7 @@ Editor::analyze_range_selection()
#endif /* FFT_ANALYSIS */
Menu*
-Editor::build_track_selection_context_menu (nframes_t ignored)
+Editor::build_track_selection_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_selection_context_menu.items();
@@ -1820,16 +1878,18 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
if (region) {
ar = boost::dynamic_pointer_cast<AudioRegion> (region);
mr = boost::dynamic_pointer_cast<MidiRegion> (region);
- }
- /* when this particular menu pops up, make the relevant region
- become selected.
- */
+ /* when this particular menu pops up, make the relevant region
+ become selected.
+ */
- region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+ region_menu->signal_map_event().connect (
+ bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+
+ items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
+ items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+ }
- items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
- items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun (*this, &Editor::lower_region_to_bottom)));
items.push_back (SeparatorElem());
@@ -1851,49 +1911,61 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
sigc::connection fooc;
- items.push_back (CheckMenuElem (_("Lock")));
- CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
- if (region->locked()) {
- region_lock_item->set_active();
- }
- region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
+ if (region) {
+ items.push_back (CheckMenuElem (_("Lock")));
+ CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
+ if (region->locked()) {
+ region_lock_item->set_active();
+ }
+ region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
- items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
- CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
+ items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
+ CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
- switch (region->positional_lock_style()) {
- case Region::MusicTime:
- bbt_glue_item->set_active (true);
- break;
- default:
- bbt_glue_item->set_active (false);
- break;
- }
+ switch (region->positional_lock_style()) {
+ case Region::MusicTime:
+ bbt_glue_item->set_active (true);
+ break;
+ default:
+ bbt_glue_item->set_active (false);
+ break;
+ }
- bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
+ bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
- items.push_back (CheckMenuElem (_("Mute")));
- CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
- fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
- if (region->muted()) {
- fooc.block (true);
- region_mute_item->set_active();
- fooc.block (false);
- }
-
- if (!Profile->get_sae()) {
- items.push_back (CheckMenuElem (_("Opaque")));
- CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
- fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
- if (region->opaque()) {
+ items.push_back (CheckMenuElem (_("Mute")));
+ CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
+ fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
+ if (region->muted()) {
fooc.block (true);
- region_opaque_item->set_active();
+ region_mute_item->set_active();
fooc.block (false);
}
+
+ if (!Profile->get_sae()) {
+ items.push_back (CheckMenuElem (_("Opaque")));
+ CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
+ fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
+ if (region->opaque()) {
+ fooc.block (true);
+ region_opaque_item->set_active();
+ fooc.block (false);
+ }
+ }
+ } else {
+ // multiple regions selected
+ // how should these act?
+ // here they toggle the property of all selected regions
+
+ items.push_back (MenuElem (_("Lock"), mem_fun(*this, &Editor::toggle_region_lock)));
+ items.push_back (MenuElem (_("Mute"), mem_fun(*this, &Editor::toggle_region_mute)));
+ if (!Profile->get_sae()) {
+ items.push_back (MenuElem (_("Opaque"), mem_fun(*this, &Editor::toggle_region_opaque)));
+ }
}
items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
- if (region->at_natural_position()) {
+ if (region && region->at_natural_position()) {
items.back().set_sensitive (false);
}
@@ -1985,7 +2057,7 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true))));
items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
+ items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_selected_regions)));
/* OK, stick the region submenu at the top of the list, and then add
the standard items.
@@ -1996,7 +2068,7 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
*/
string::size_type pos = 0;
- string menu_item_name = region->name();
+ string menu_item_name = (region) ? region->name() : _("Selected regions");
while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
menu_item_name.replace (pos, 1, "__");
@@ -2049,7 +2121,8 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)));
items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection)));
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Bounce range"), mem_fun(*this, &Editor::bounce_range_selection)));
+ items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true)));
+ items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false)));
items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection)));
}
@@ -2199,8 +2272,9 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
void
Editor::set_snap_to (SnapType st)
-{
+{
unsigned int snap_ind = (unsigned int)st;
+
snap_type = st;
if (snap_ind > snap_type_strings.size() - 1) {
@@ -2355,7 +2429,7 @@ Editor::set_state (const XMLNode& node)
move (x, y);
if (session && (prop = node.property ("playhead"))) {
- nframes_t pos = atol (prop->value().c_str());
+ nframes64_t pos = atol (prop->value().c_str());
playhead_cursor->set_position (pos);
} else {
playhead_cursor->set_position (0);
@@ -2546,7 +2620,7 @@ Editor::get_state ()
node->add_property ("edit-point", enum_2_string (_edit_point));
- snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
+ snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame);
node->add_property ("playhead", buf);
node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no");
@@ -2614,17 +2688,17 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
switch (snap_type) {
case SnapToCDFrame:
if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
+ start = (nframes64_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
} else {
- start = (nframes_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
+ start = (nframes64_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
}
break;
case SnapToSMPTEFrame:
if (((direction == 0) && (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2))) || (direction > 0)) {
- start = (nframes_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+ start = (nframes64_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
} else {
- start = (nframes_t) (floor ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+ start = (nframes64_t) (floor ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
}
break;
@@ -2636,9 +2710,9 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
start -= session->smpte_offset ();
}
if (((direction == 0) && (start % one_smpte_second > one_smpte_second / 2)) || direction > 0) {
- start = (nframes_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
+ start = (nframes64_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
} else {
- start = (nframes_t) floor ((double) start / one_smpte_second) * one_smpte_second;
+ start = (nframes64_t) floor ((double) start / one_smpte_second) * one_smpte_second;
}
if (session->smpte_offset_negative())
@@ -2657,9 +2731,9 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
start -= session->smpte_offset ();
}
if (((direction == 0) && (start % one_smpte_minute > one_smpte_minute / 2)) || direction > 0) {
- start = (nframes_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
+ start = (nframes64_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
} else {
- start = (nframes_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
+ start = (nframes64_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
}
if (session->smpte_offset_negative())
{
@@ -2671,17 +2745,17 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
case SnapToSeconds:
if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / one_second) * one_second;
+ start = (nframes64_t) ceil ((double) start / one_second) * one_second;
} else {
- start = (nframes_t) floor ((double) start / one_second) * one_second;
+ start = (nframes64_t) floor ((double) start / one_second) * one_second;
}
break;
case SnapToMinutes:
if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / one_minute) * one_minute;
+ start = (nframes64_t) ceil ((double) start / one_minute) * one_minute;
} else {
- start = (nframes_t) floor ((double) start / one_minute) * one_minute;
+ start = (nframes64_t) floor ((double) start / one_minute) * one_minute;
}
break;
@@ -2758,7 +2832,7 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
case SnapToRegionSync:
case SnapToRegionBoundary:
if (!region_boundary_cache.empty()) {
- vector<nframes_t>::iterator i;
+ vector<nframes64_t>::iterator i;
if (direction > 0) {
i = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
@@ -2808,7 +2882,7 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
}
double
-Editor::snap_length_beats (nframes_t start)
+Editor::snap_length_beats (nframes64_t start)
{
if (!session) {
return 1.0;
@@ -3685,6 +3759,8 @@ Editor::zoom_focus_selection_done ()
focus_type = ZoomFocusEdit;
} else if (choice == _("Active Mark")) {
focus_type = ZoomFocusEdit;
+ } else if (choice == _("Active Mark")) {
+ focus_type = ZoomFocusEdit;
} else {
focus_type = ZoomFocusMouse;
}
@@ -3923,10 +3999,10 @@ Editor::playlist_selector () const
return *_playlist_selector;
}
-nframes_t
-Editor::get_nudge_distance (nframes_t pos, nframes_t& next)
+nframes64_t
+Editor::get_nudge_distance (nframes64_t pos, nframes64_t& next)
{
- nframes_t ret;
+ nframes64_t ret;
ret = nudge_clock.current_duration (pos);
next = ret + 1; /* XXXX fix me */
@@ -3978,7 +4054,7 @@ Editor::playlist_deletion_dialog (boost::shared_ptr<Playlist> pl)
}
bool
-Editor::audio_region_selection_covers (nframes_t where)
+Editor::audio_region_selection_covers (nframes64_t where)
{
for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
if ((*a)->region()->covers (where)) {
@@ -3997,6 +4073,15 @@ Editor::prepare_for_cleanup ()
selection->clear_regions ();
selection->clear_playlists ();
+
+ no_region_list_redisplay = true;
+}
+
+void
+Editor::finish_cleanup ()
+{
+ no_region_list_redisplay = false;
+ redisplay_regions ();
}
Location*
@@ -4212,8 +4297,8 @@ Editor::maximise_editing_space ()
post_maximal_pane_position = edit_pane.get_width();
}
-
fullscreen();
+
if(post_maximal_editor_width) {
edit_pane.set_position (post_maximal_pane_position -
abs(post_maximal_editor_width - pre_maximal_editor_width));
@@ -4318,7 +4403,7 @@ Editor::on_key_release_event (GdkEventKey* ev)
}
void
-Editor::reset_x_origin (nframes_t frame)
+Editor::reset_x_origin (nframes64_t frame)
{
queue_visual_change (frame);
}
@@ -4330,28 +4415,97 @@ Editor::reset_zoom (double fpu)
}
void
-Editor::reposition_and_zoom (nframes_t frame, double fpu)
+Editor::reposition_and_zoom (nframes64_t frame, double fpu)
{
+ //cerr << "Editor::reposition_and_zoom () called ha v:l:u:ps:fpu = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << frames_per_unit << endl;//DEBUG
reset_x_origin (frame);
reset_zoom (fpu);
+
+ if (!no_save_visual) {
+ undo_visual_stack.push_back (current_visual_state(false));
+ }
+}
+
+Editor::VisualState*
+Editor::current_visual_state (bool with_tracks)
+{
+ VisualState* vs = new VisualState;
+ vs->y_position = vertical_adjustment.get_value();
+ vs->frames_per_unit = frames_per_unit;
+ vs->leftmost_frame = leftmost_frame;
+ vs->zoom_focus = zoom_focus;
+ vs->zoomed_to_region = zoomed_to_region;
+
+ if (with_tracks) {
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ vs->track_states.push_back (TAVState ((*i), &(*i)->get_state()));
+ }
+ }
+
+ return vs;
}
void
-Editor::swap_visual_state ()
+Editor::undo_visual_state ()
{
- if (last_visual_state.frames_per_unit == 0) {
- // never set
+ if (undo_visual_stack.empty()) {
return;
}
- /* note: the correct functionality here is very dependent on the ordering of
- setting zoom focus, horizontal position and finally zoom. this is because
- it is set_frames_per_unit() that overwrites last_visual_state.
- */
+ VisualState* vs = undo_visual_stack.back();
+ undo_visual_stack.pop_back();
+ use_visual_state (*vs);
+ redo_visual_stack.push_back (vs);
+}
- set_zoom_focus (last_visual_state.zoom_focus);
- reposition_and_zoom (last_visual_state.leftmost_frame, last_visual_state.frames_per_unit);
- zoomed_to_region = false;
+void
+Editor::redo_visual_state ()
+{
+ if (redo_visual_stack.empty()) {
+ return;
+ }
+
+ VisualState* vs = redo_visual_stack.back();
+ redo_visual_stack.pop_back();
+ use_visual_state (*vs);
+ undo_visual_stack.push_back (vs);
+}
+
+void
+Editor::swap_visual_state ()
+{
+ if (undo_visual_stack.empty()) {
+ redo_visual_state ();
+ } else {
+ undo_visual_state ();
+ }
+}
+
+void
+Editor::use_visual_state (VisualState& vs)
+{
+ no_save_visual = true;
+
+ vertical_adjustment.set_value (vs.y_position);
+
+ set_zoom_focus (vs.zoom_focus);
+ reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
+
+ for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) {
+ TrackViewList::iterator t;
+
+ /* check if the track still exists - it could have been deleted */
+
+ if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) {
+ (*t)->set_state (*(i->second));
+ }
+ }
+
+ if (!vs.track_states.empty()) {
+ update_route_visibility ();
+ }
+
+ no_save_visual = false;
}
void
@@ -4381,10 +4535,6 @@ Editor::set_frames_per_unit (double fpu)
if (fpu == frames_per_unit) {
return;
}
-
- last_visual_state.frames_per_unit = frames_per_unit;
- last_visual_state.leftmost_frame = leftmost_frame;
- last_visual_state.zoom_focus = zoom_focus;
frames_per_unit = fpu;
post_zoom ();
@@ -4395,7 +4545,7 @@ Editor::post_zoom ()
{
// convert fpu to frame count
- nframes_t frames = (nframes_t) floor (frames_per_unit * canvas_width);
+ nframes64_t frames = (nframes64_t) floor (frames_per_unit * canvas_width);
if (frames_per_unit != zoom_range_clock.current_duration()) {
zoom_range_clock.set (frames);
@@ -4424,11 +4574,11 @@ Editor::post_zoom ()
}
void
-Editor::queue_visual_change (nframes_t where)
+Editor::queue_visual_change (nframes64_t where)
{
pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
pending_visual_change.time_origin = where;
-
+
if (pending_visual_change.idle_handler_id < 0) {
pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
}
@@ -4456,6 +4606,12 @@ int
Editor::idle_visual_changer ()
{
VisualChange::Type p = pending_visual_change.pending;
+ nframes64_t csf, cef;
+
+ if (session) {
+ csf = session->current_start_frame();
+ cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker
+ }
pending_visual_change.pending = (VisualChange::Type) 0;
@@ -4469,17 +4625,26 @@ Editor::idle_visual_changer ()
}
if (p & VisualChange::TimeOrigin) {
- nframes_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+ nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+ /* if we seek beyond the current end of the canvas, move the end */
if (time_origin != pending_visual_change.time_origin) {
+
+ if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) {
+ last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames();
+ horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit);
+ reset_scrolling_region ();
+ }
+
horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
} else {
update_fixed_rulers();
redisplay_tempo (true);
}
}
- pending_visual_change.idle_handler_id = -1;
+ pending_visual_change.idle_handler_id = -1;
return 0; /* this is always a one-shot call */
}
@@ -4550,7 +4715,7 @@ Editor::get_preferred_edit_position (bool ignore_playhead)
}
void
-Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd)
{
if (!session) return;
@@ -4577,7 +4742,7 @@ Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
}
void
-Editor::set_punch_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd)
{
if (!session) return;
@@ -4625,14 +4790,14 @@ Editor::get_regions_at (RegionSelection& rs, nframes64_t where, const TrackSelec
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)where * ds->speed()));
+ Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)where * ds->speed()));
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
RegionView* rv = atv->audio_view()->find_view (*i);
if (rv) {
- rs.push_back (rv);
+ rs.add (rv);
}
}
@@ -4663,7 +4828,7 @@ Editor::get_regions_after (RegionSelection& rs, nframes64_t where, const TrackSe
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_touched ((nframes_t) floor ( (double)where * ds->speed()), max_frames);
+ Playlist::RegionList* regions = pl->regions_touched ((nframes64_t) floor ( (double)where * ds->speed()), max_frames);
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
@@ -4809,3 +4974,170 @@ Editor::first_idle ()
_have_idled = true;
}
+
+void
+Editor::start_resize_line_ops ()
+{
+#if 0
+ old_resize_line_y = -1;
+ resize_line_y = -1;
+ need_resize_line = true;
+#endif
+}
+
+void
+Editor::end_resize_line_ops ()
+{
+#if 0
+ need_resize_line = false;
+
+ if (old_resize_line_y >= 0) {
+ Gdk::Rectangle r (0, old_resize_line_y, (int) canvas_width, 3);
+ Glib::RefPtr<Gdk::Window> win = get_window();
+ cerr << "Final invalidation at " << old_resize_line_y << endl;
+ win->invalidate_rect (r, false);
+ }
+#endif
+}
+
+void
+Editor::queue_draw_resize_line (int at)
+{
+#if 0
+ Glib::RefPtr<Gdk::Window> win = get_window();
+
+ resize_line_y = at;
+
+ if (win && canvas_width) {
+
+ int controls_width = controls_layout.get_width();
+ int xroot, discard;
+
+ controls_layout.get_window()->get_origin (xroot, discard);
+
+ if (old_resize_line_y >= 0) {
+
+ /* redraw where it used to be */
+
+
+ Gdk::Rectangle r (xroot, old_resize_line_y - 1, controls_width + (int) canvas_width, 3);
+ win->invalidate_rect (r, true);
+ cerr << "invalidate " << xroot << "," << old_resize_line_y - 1 << ' '
+ << controls_width + canvas_width << " x 3\n";
+ }
+
+ /* draw where it is */
+
+ Gdk::Rectangle r (xroot, at - 1, controls_width + (int) canvas_width, 3);
+ win->invalidate_rect (r, true);
+ }
+#endif
+}
+
+bool
+Editor::on_expose_event (GdkEventExpose* ev)
+{
+ /* cerr << "+++ editor expose "
+ << ev->area.x << ',' << ev->area.y
+ << ' '
+ << ev->area.width << " x " << ev->area.height
+ << " need reize ? " << need_resize_line
+ << endl;
+ */
+ bool ret = Window::on_expose_event (ev);
+
+#if 0
+ if (need_resize_line) {
+
+ int xroot, yroot, discard;
+ int controls_width;
+
+ /* Our root coordinates for drawing the line will be the left edge
+ of the track controls, and the upper left edge of our own window.
+ */
+
+ get_window()->get_origin (discard, yroot);
+ controls_layout.get_window()->get_origin (xroot, discard);
+ controls_width = controls_layout.get_width();
+
+ GdkRectangle lr;
+ GdkRectangle intersection;
+
+ lr.x = xroot;
+ lr.y = resize_line_y;
+ lr.width = controls_width + (int) canvas_width;
+ lr.height = 3;
+
+ if (gdk_rectangle_intersect (&lr, &ev->area, &intersection)) {
+
+ Glib::RefPtr<Gtk::Style> style (get_style());
+ Glib::RefPtr<Gdk::GC> black_gc (style->get_black_gc ());
+ Glib::RefPtr<Gdk::GC> gc = wrap (black_gc->gobj_copy(), false);
+
+ /* draw on root window */
+
+ GdkWindow* win = gdk_get_default_root_window();
+
+ gc->set_subwindow (Gdk::INCLUDE_INFERIORS);
+ gc->set_line_attributes (3, Gdk::LINE_SOLID,
+ Gdk::CAP_NOT_LAST,
+ Gdk::JOIN_MITER);
+
+ gdk_draw_line (win, gc->gobj(),
+ xroot,
+ yroot + resize_line_y,
+ xroot + (int) canvas_width + controls_width,
+ yroot + resize_line_y);
+ cerr << "drew line @ " << xroot << ", " << yroot + resize_line_y
+ << " to " << xroot + (int) canvas_width + controls_width
+ << ", " << yroot + resize_line_y
+ << endl;
+ old_resize_line_y = yroot + resize_line_y;
+ cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl;
+ } else {
+ cerr << "no intersect with "
+ << lr.x << ',' << lr.y
+ << ' '
+ << lr.width << " x " << lr.height
+ << endl;
+ }
+ }
+
+ //cerr << "--- editor expose\n";
+#endif
+
+ return ret;
+}
+
+static gboolean
+_idle_resizer (gpointer arg)
+{
+ return ((Editor*)arg)->idle_resize ();
+}
+
+void
+Editor::add_to_idle_resize (TimeAxisView* view, uint32_t h)
+{
+ if (resize_idle_id < 0) {
+ resize_idle_id = g_idle_add (_idle_resizer, this);
+ }
+
+ resize_idle_target = h;
+
+ pending_resizes.push_back (view);
+
+ if (selection->selected (view) && !selection->tracks.empty()) {
+ pending_resizes.insert (pending_resizes.end(), selection->tracks.begin(), selection->tracks.end());
+ }
+}
+
+bool
+Editor::idle_resize ()
+{
+ for (vector<TimeAxisView*>::iterator i = pending_resizes.begin(); i != pending_resizes.end(); ++i) {
+ (*i)->idle_resize (resize_idle_target);
+ }
+ pending_resizes.clear();
+ resize_idle_id = -1;
+ return false;
+}