#include "ardour/session.h"
#include "ardour/location.h"
#include "ardour/tempo.h"
+#include "ardour/utils.h"
#include "control_protocol/basic_ui.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace ARDOUR;
void
BasicUI::loop_toggle ()
{
+ if (!session) {
+ return;
+ }
+
+ Location * looploc = session->locations()->auto_loop_location();
+
+ if (!looploc) {
+ return;
+ }
+
if (session->get_play_loop()) {
+
+ /* looping enabled, our job is to disable it */
+
session->request_play_loop (false);
+
} else {
- session->request_play_loop (true);
- if (!session->transport_rolling()) {
- session->request_transport_speed (1.0);
+
+ /* looping not enabled, our job is to enable it.
+
+ loop-is-NOT-mode: this action always starts the transport rolling.
+ loop-IS-mode: this action simply sets the loop play mechanism, but
+ does not start transport.
+ */
+ if (Config->get_loop_is_mode()) {
+ session->request_play_loop (true, false);
+ } else {
+ session->request_play_loop (true, true);
}
}
+
+ //show the loop markers
+ looploc->set_hidden (false, this);
}
void
void
BasicUI::transport_play (bool from_last_start)
{
- bool rolling = session->transport_rolling ();
+ if (!session) {
+ return;
+ }
- if (session->get_play_loop()) {
- session->request_play_loop (false);
+ if (session->is_auditioning()) {
+ return;
}
- if (session->get_play_range ()) {
- session->request_play_range (0);
+#if 0
+ if (session->config.get_external_sync()) {
+ switch (Config->get_sync_source()) {
+ case Engine:
+ break;
+ default:
+ /* transport controlled by the master */
+ return;
+ }
}
+#endif
+
+ bool rolling = session->transport_rolling();
- if (from_last_start && rolling) {
- session->request_locate (session->last_transport_start(), true);
+ if (session->get_play_loop()) {
+
+ /* If loop playback is not a mode, then we should cancel
+ it when this action is requested. If it is a mode
+ we just leave it in place.
+ */
+ if (!Config->get_loop_is_mode()) {
+ /* XXX it is not possible to just leave seamless loop and keep
+ playing at present (nov 4th 2009)
+ */
+ if (!Config->get_seamless_loop()) {
+ /* stop loop playback and stop rolling */
+ session->request_play_loop (false, true);
+ } else if (rolling) {
+ /* stop loop playback but keep rolling */
+ session->request_play_loop (false, false);
+ }
+ }
+
+ } else if (session->get_play_range () ) {
+ /* stop playing a range if we currently are */
+ session->request_play_range (0, true);
}
- session->request_transport_speed (1.0f);
+ if (!rolling) {
+ session->request_transport_speed (1.0f);
+ }
}
void
{
framepos_t current = session->transport_frame();
double s = (double) current / (double) session->nominal_frame_rate();
-
+
s+= secs;
if (s < 0) current = 0;
s = s * session->nominal_frame_rate();
-
+
session->request_locate ( floor(s) );
}
void
BasicUI::jump_by_bars (double bars)
{
- Timecode::BBT_Time bbt;
TempoMap& tmap (session->tempo_map());
- tmap.bbt_time (session->transport_frame(), bbt);
+ Timecode::BBT_Time bbt (tmap.bbt_at_frame (session->transport_frame()));
bars += bbt.bars;
if (bars < 0) bars = 0;
-
+
AnyTime any;
any.type = AnyTime::BBT;
any.bbt.bars = bars;
-
+
session->request_locate ( session->convert_to_frames (any) );
}
session->sample_to_timecode (sample, *((Timecode::Time*)&timecode), use_offset, use_subframes);
}
+void
+BasicUI::toggle_selection (PresentationInfo::order_t o, PresentationInfo::Flag flags)
+{
+ boost::shared_ptr<Stripable> s = session->get_remote_nth_stripable (o, flags);
+
+ if (s) {
+ s->presentation_info().set_selected (!s->presentation_info().selected());
+ }
+}
+
+void
+BasicUI::clear_stripable_selection ()
+{
+ session->clear_stripable_selection ();
+}
+
+void
+BasicUI::toggle_stripable_selection (boost::shared_ptr<Stripable> s)
+{
+ session->toggle_stripable_selection (s);
+}
+
+void
+BasicUI::add_stripable_selection (boost::shared_ptr<Stripable> s)
+{
+ session->add_stripable_selection (s);
+}
+
+void
+BasicUI::set_stripable_selection (boost::shared_ptr<Stripable> s)
+{
+ session->set_stripable_selection (s);
+}
+
+
+void
+BasicUI::cancel_all_solo ()
+{
+ if (session) {
+ session->cancel_all_solo ();
+ }
+}
+
+struct SortLocationsByPosition {
+ bool operator() (Location* a, Location* b) {
+ return a->start() < b->start();
+ }
+};
+
+void
+BasicUI::goto_nth_marker (int n)
+{
+ if (!session) {
+ return;
+ }
+
+ const Locations::LocationList& l (session->locations()->list());
+ Locations::LocationList ordered;
+ ordered = l;
+
+ SortLocationsByPosition cmp;
+ ordered.sort (cmp);
+
+ for (Locations::LocationList::iterator i = ordered.begin(); n >= 0 && i != ordered.end(); ++i) {
+ if ((*i)->is_mark() && !(*i)->is_hidden() && !(*i)->is_session_range()) {
+ if (n == 0) {
+ session->request_locate ((*i)->start(), session->transport_rolling());
+ break;
+ }
+ --n;
+ }
+ }
+}
+
#if 0
this stuff is waiting to go in so that all UIs can offer complex solo/mute functionality