insert time operation

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3203 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-04-01 16:49:42 +00:00
parent 9d415be53e
commit bc3b41703e
16 changed files with 238 additions and 9 deletions

View File

@ -232,6 +232,7 @@
<menu action='TrackMenu'>
<menuitem action='AddTrackBus'/>
<menuitem action='insert-time'/>
<menu action='TrackHeightMenu'>
<menuitem action='track-height-largest'/>
<menuitem action='track-height-large'/>

View File

@ -1341,6 +1341,7 @@ widget "*EditPointClock" style:highest "default_clock_display"
widget "*PreRollClock" style:highest "default_clock_display"
widget "*PostRollClock" style:highest "default_clock_display"
widget "*NudgeClock" style:highest "default_clock_display"
widget "*InsertTimeClock" style:highest "default_clock_display"
widget "*ZoomRangeClock" style:highest "default_clock_display"
widget "*SMPTEOffsetClock" style:highest "default_clock_display"
widget "*TransportLabel" style:highest "small_bold_text"

View File

@ -1344,6 +1344,7 @@ widget "*EditPointClock" style:highest "default_clock_display"
widget "*PreRollClock" style:highest "default_clock_display"
widget "*PostRollClock" style:highest "default_clock_display"
widget "*NudgeClock" style:highest "default_clock_display"
widget "*InsertTimeClock" style:highest "default_clock_display"
widget "*ZoomRangeClock" style:highest "default_clock_display"
widget "*SMPTEOffsetClock" style:highest "default_clock_display"
widget "*TransportLabel" style:highest "small_bold_text"

View File

@ -83,7 +83,8 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg
key_entry_state = 0;
ops_menu = 0;
dragging = false;
bbt_reference_time = -1;
if (with_info) {
frames_upper_info_label = manage (new Label);
frames_lower_info_label = manage (new Label);
@ -641,7 +642,16 @@ AudioClock::set_bbt (nframes_t when, bool force)
ticks_label.set_text (buf);
if (bbt_upper_info_label) {
TempoMap::Metric m (session->tempo_map().metric_at (when));
nframes64_t pos;
if (bbt_reference_time < 0) {
pos = when;
} else {
pos = bbt_reference_time;
}
TempoMap::Metric m (session->tempo_map().metric_at (pos));
sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
if (bbt_lower_info_label->get_text() != buf) {
bbt_lower_info_label->set_text (buf);
@ -1995,3 +2005,9 @@ AudioClock::set_size_requests ()
}
}
void
AudioClock::set_bbt_reference (nframes64_t pos)
{
bbt_reference_time = pos;
}

View File

@ -50,7 +50,8 @@ class AudioClock : public Gtk::HBox
void set (nframes_t, bool force = false, nframes_t offset = 0, int which = 0);
void set_mode (Mode);
void set_bbt_reference (nframes64_t);
void set_widget_name (std::string);
std::string name() const { return _name; }
@ -154,6 +155,7 @@ class AudioClock : public Gtk::HBox
Gtk::EventBox clock_base;
Gtk::Frame clock_frame;
nframes64_t bbt_reference_time;
nframes_t last_when;
bool last_pdelta;
bool last_sdelta;

View File

@ -38,6 +38,7 @@
#define EDITPOINT(a) /*empty*/
#define WAVEFORMSCALE(a) /*empty*/
#define WAVEFORMSHAPE(a) /*empty*/
#define INSERTTIMEOPT(a) /*empty*/
namespace Editing {
@ -186,6 +187,18 @@ enum WaveformShape {
#undef WAVEFORMSHAPE
#define WAVEFORMSHAPE(a) /*empty*/
// INSERTTIMEOPT
#undef INSERTTIMEOPT
#define INSERTTIMEOPT(a) a,
enum InsertTimeOption {
#include "editing_syms.h"
};
#undef INSERTTIMEOPT
#define INSERTTIMEOPT(a) /*empty*/
/////////////////////
// These don't need their state saved. yet...
enum CutCopyOp {

View File

@ -102,3 +102,6 @@ WAVEFORMSHAPE(Traditional)
WAVEFORMSHAPE(Rectified)
INSERTTIMEOPT(LeaveIntersected)
INSERTTIMEOPT(MoveIntersected)
INSERTTIMEOPT(SplitIntersected)

View File

@ -1012,6 +1012,9 @@ class Editor : public PublicEditor
void denormalize_region ();
void adjust_region_scale_amplitude (bool up);
void do_insert_time ();
void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue);
void tab_to_transient (bool forward);
void use_region_as_bar ();

View File

@ -502,6 +502,10 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "remove-last-capture", _("Remove Last Capture"), (mem_fun(*this, &Editor::remove_last_capture)));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "insert-time", _("Insert Time"), (mem_fun(*this, &Editor::do_insert_time)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "toggle-track-active", _("Toggle Active"), (mem_fun(*this, &Editor::toggle_tracks_active)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);

View File

@ -5639,4 +5639,118 @@ Editor::set_waveform_scale (WaveformScale ws)
}
}
}
void
Editor::do_insert_time ()
{
if (selection->tracks.empty()) {
return;
}
nframes64_t pos = get_preferred_edit_position ();
ArdourDialog d (*this, _("Insert Time"));
VButtonBox button_box;
VBox option_box;
RadioButtonGroup group;
RadioButton leave_button (group, _("Stay in position"));
RadioButton move_button (group, _("Move"));
RadioButton split_button (group, _("Split & Later Section Moves"));
Label intersect_option_label (_("Intersected regions should:"));
ToggleButton glue_button (_("Move Glued Regions"));
AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
HBox clock_box;
clock.set (0);
clock.set_session (session);
clock.set_bbt_reference (pos);
clock_box.pack_start (clock, false, true);
option_box.set_spacing (6);
option_box.pack_start (intersect_option_label, false, false);
option_box.pack_start (button_box, false, false);
option_box.pack_start (glue_button, false, false);
button_box.pack_start (leave_button, false, false);
button_box.pack_start (move_button, false, false);
button_box.pack_start (split_button, false, false);
d.get_vbox()->set_border_width (12);
d.get_vbox()->pack_start (clock_box, false, false);
d.get_vbox()->pack_start (option_box, false, false);
leave_button.show ();
move_button.show ();
split_button.show ();
intersect_option_label.show ();
option_box.show ();
button_box.show ();
glue_button.show ();
clock.show_all();
clock_box.show ();
d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
d.show ();
int response = d.run ();
if (response != RESPONSE_OK) {
return;
}
nframes_t distance = clock.current_duration (pos);
if (distance == 0) {
return;
}
InsertTimeOption opt;
if (leave_button.get_active()) {
opt = LeaveIntersected;
} else if (move_button.get_active()) {
opt = MoveIntersected;
} else {
opt = SplitIntersected;
}
insert_time (pos, distance, opt, glue_button.get_active());
}
void
Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, bool ignore_music_glue)
{
bool commit = false;
if (Config->get_edit_mode() == Lock) {
return;
}
begin_reversible_command (_("insert time"));
for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
boost::shared_ptr<Playlist> pl = (*x)->playlist();
if (!pl) {
continue;
}
XMLNode &before = pl->get_state();
if (opt == SplitIntersected) {
pl->split (pos);
}
pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
XMLNode &after = pl->get_state();
session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
commit = true;
}
if (commit) {
commit_reversible_command ();
}
}

View File

@ -57,6 +57,7 @@
(gtk_accel_path "<Actions>/Editor/redo" "<%PRIMARY%>r")
(gtk_accel_path "<Actions>/Transport/Record" "<%TERTIARY%>r")
(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
(gtk_accel_path "<Actions>/Editor/insert-time" "<%PRIMARY%>t")
(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "u")
(gtk_accel_path "<Actions>/Editor/insert-region" "i")
(gtk_accel_path "<Actions>/Editor/invert-selection" "<%TERTIARY%>i")

View File

@ -89,6 +89,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos);
void split_region (boost::shared_ptr<Region>, nframes_t position);
void split (nframes64_t at);
void shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue);
void partition (nframes_t start, nframes_t end, bool just_top_level);
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
@ -276,6 +278,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
void unset_freeze_child (Playlist*);
void timestamp_layer_op (boost::shared_ptr<Region>);
void _split_region (boost::shared_ptr<Region>, nframes_t position);
};
} /* namespace ARDOUR */

View File

@ -128,6 +128,7 @@ class Region : public PBD::StatefulDestructible, public Readable, public boost::
PositionLockStyle positional_lock_style() const { return _positional_lock_style; }
void set_position_lock_style (PositionLockStyle ps);
void recompute_position_from_lock_style ();
virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };

View File

@ -1013,11 +1013,68 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
}
}
void
Playlist::shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue)
{
RegionLock rlock (this);
RegionList copy (regions);
RegionList fixup;
for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
if ((*r)->last_frame() < at) {
/* too early */
continue;
}
if (at > (*r)->first_frame() && at < (*r)->last_frame()) {
/* intersected region */
if (!move_intersected) {
continue;
}
}
/* do not move regions glued to music time - that
has to be done separately.
*/
if (!ignore_music_glue && (*r)->positional_lock_style() != Region::AudioTime) {
fixup.push_back (*r);
continue;
}
(*r)->set_position ((*r)->position() + distance, this);
}
for (RegionList::iterator r = fixup.begin(); r != fixup.end(); ++r) {
(*r)->recompute_position_from_lock_style ();
}
}
void
Playlist::split (nframes64_t at)
{
RegionLock rlock (this);
RegionList copy (regions);
/* use a copy since this operation can modify the region list
*/
for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
_split_region (*r, at);
}
}
void
Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
{
RegionLock rl (this);
_split_region (region, playlist_position);
}
void
Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
{
if (!region->covers (playlist_position)) {
return;
}

View File

@ -352,11 +352,8 @@ Region::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
_length = max_frames - _position;
}
if (allow_bbt_recompute && _positional_lock_style == MusicTime) {
boost::shared_ptr<Playlist> pl (playlist());
if (pl) {
pl->session().tempo_map().bbt_time (_position, _bbt_time);
}
if (allow_bbt_recompute) {
recompute_position_from_lock_style ();
}
invalidate_transients ();
@ -394,6 +391,17 @@ Region::set_position_on_top (nframes_t pos, void *src)
send_change (PositionChanged);
}
void
Region::recompute_position_from_lock_style ()
{
if (_positional_lock_style == MusicTime) {
boost::shared_ptr<Playlist> pl (playlist());
if (pl) {
pl->session().tempo_map().bbt_time (_position, _bbt_time);
}
}
}
void
Region::nudge_position (nframes64_t n, void *src)
{

View File

@ -1,4 +1,4 @@
#ifndef __ardour_svn_revision_h__
#define __ardour_svn_revision_h__
static const char* ardour_svn_revision = "3200";
static const char* ardour_svn_revision = "3201";
#endif