clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
clock_base.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &AudioClock::field_button_release_event), Timecode_Hours));
- Session::TimecodeOffsetChanged.connect (_session_connections, invalidator (*this), boost::bind (&AudioClock::timecode_offset_changed, this), gui_context());
-
if (editable) {
setup_events ();
}
}
void
-AudioClock::timecode_offset_changed ()
+AudioClock::session_configuration_changed (std::string p)
{
+ if (p != "timecode-offset" && p != "timecode-offset-negative") {
+ return;
+ }
+
nframes_t current;
switch (_mode) {
if (_session) {
+ _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&AudioClock::session_configuration_changed, this, _1), gui_context());
+
XMLProperty* prop;
XMLNode* node = _session->extra_xml (X_("ClockModes"));
AudioClock::Mode amode;
void build_ops_menu ();
void setup_events ();
- void timecode_offset_changed ();
+ void session_configuration_changed (std::string);
void set_size_requests ();
static const uint32_t field_length[(int)AudioFrames+1];
_session->PositionChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::map_position_change, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Editor::handle_new_route, this, _1), gui_context());
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
- _session->TimecodeOffsetChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_just_timecode, this), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::tempo_map_changed, this, _1), gui_context());
_session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::parameter_changed, this, _1), gui_context());
break;
case SnapToTimecodeSeconds:
- if (_session->timecode_offset_negative())
- {
- start += _session->timecode_offset ();
+ if (_session->config.get_timecode_offset_negative()) {
+ start += _session->config.get_timecode_offset ();
} else {
- start -= _session->timecode_offset ();
+ start -= _session->config.get_timecode_offset ();
}
if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) {
start = (framepos_t) ceil ((double) start / one_timecode_second) * one_timecode_second;
start = (framepos_t) floor ((double) start / one_timecode_second) * one_timecode_second;
}
- if (_session->timecode_offset_negative())
- {
- start -= _session->timecode_offset ();
+ if (_session->config.get_timecode_offset_negative()) {
+ start -= _session->config.get_timecode_offset ();
} else {
- start += _session->timecode_offset ();
+ start += _session->config.get_timecode_offset ();
}
break;
case SnapToTimecodeMinutes:
- if (_session->timecode_offset_negative())
- {
- start += _session->timecode_offset ();
+ if (_session->config.get_timecode_offset_negative()) {
+ start += _session->config.get_timecode_offset ();
} else {
- start -= _session->timecode_offset ();
+ start -= _session->config.get_timecode_offset ();
}
if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) {
start = (framepos_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute;
} else {
start = (framepos_t) floor ((double) start / one_timecode_minute) * one_timecode_minute;
}
- if (_session->timecode_offset_negative())
- {
- start -= _session->timecode_offset ();
+ if (_session->config.get_timecode_offset_negative()) {
+ start -= _session->config.get_timecode_offset ();
} else {
- start += _session->timecode_offset ();
+ start += _session->config.get_timecode_offset ();
}
break;
default:
tact->set_active (s);
}
}
+ } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
+ update_just_timecode ();
}
}
add_widgets_to_page (p, &_label, &_box);
}
+ClockOption::ClockOption (string const & i, string const & n, sigc::slot<framecnt_t> g, sigc::slot<bool, framecnt_t> s)
+ : Option (i, n)
+ , _clock (X_("timecode-offset"), false, X_("TimecodeOffset"), true, false, true, false)
+ , _get (g)
+ , _set (s)
+{
+ _label.set_text (n + ":");
+ _label.set_alignment (0, 0.5);
+ _label.set_name (X_("OptionsLabel"));
+}
+
+void
+ClockOption::set_state_from_config ()
+{
+ _clock.set (_get ());
+}
+
+void
+ClockOption::add_to_page (OptionEditorPage* p)
+{
+ add_widgets_to_page (p, &_label, &_clock);
+}
+
+void
+ClockOption::set_session (Session* s)
+{
+ _clock.set_session (s);
+}
+
OptionEditorPage::OptionEditorPage (Gtk::Notebook& n, std::string const & t)
: table (1, 3)
{
#include <gtkmm/table.h>
#include "gtkmm2ext/slider_controller.h"
#include "ardour_dialog.h"
+#include "audio_clock.h"
#include "ardour/types.h"
/** @file option_editor.h
sigc::slot<bool, ARDOUR::gain_t> _set;
};
+class ClockOption : public Option
+{
+public:
+ ClockOption (std::string const &, std::string const &, sigc::slot<ARDOUR::framecnt_t>, sigc::slot<bool, ARDOUR::framecnt_t>);
+ void set_state_from_config ();
+ void add_to_page (OptionEditorPage *);
+ void set_session (ARDOUR::Session *);
+
+private:
+ Gtk::Label _label;
+ AudioClock _clock;
+ sigc::slot<ARDOUR::framecnt_t> _get;
+ sigc::slot<bool, ARDOUR::framecnt_t> _set;
+};
+
/** Class to represent a single page in an OptionEditor's notebook.
* Pages are laid out using a 3-column table; the 1st column is used
* to indent non-headings, and the 2nd and 3rd for actual content.
: OptionEditor (&(s->config), _("Session Properties"))
, _session_config (&(s->config))
{
+ set_session (s);
+
set_name ("SessionProperties");
/* SYNC */
add_option (_("Sync"), vpu);
+ ClockOption* co = new ClockOption (
+ "timecode-offset",
+ _("Timecode Offset"),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset)
+ );
+
+ co->set_session (_session);
+
+ add_option (_("Sync"), co);
+
+ add_option (_("Sync"), new BoolOption (
+ "timecode-offset-negative",
+ _("Timecode Offset Negative"),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset_negative),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset_negative)
+ ));
+
/* FADES */
ComboOption<CrossfadeModel>* cfm = new ComboOption<CrossfadeModel> (
void timecode_duration (framecnt_t, Timecode::Time&) const;
void timecode_duration_string (char *, framecnt_t) const;
- void set_timecode_offset (nframes_t);
- nframes_t timecode_offset () const { return _timecode_offset; }
- void set_timecode_offset_negative (bool);
- bool timecode_offset_negative () const { return _timecode_offset_negative; }
-
nframes_t convert_to_frames_at (nframes_t position, AnyTime const &);
static PBD::Signal1<void, framepos_t> StartTimeChanged;
static PBD::Signal1<void, framepos_t> EndTimeChanged;
- static PBD::Signal0<void> TimecodeOffsetChanged;
std::vector<SyncSource> get_available_sync_options() const;
void request_sync_source (Slave*);
double _frames_per_timecode_frame; /* has to be floating point because of drop frame */
nframes_t _frames_per_hour;
nframes_t _timecode_frames_per_hour;
- nframes_t _timecode_offset;
- bool _timecode_offset_negative;
/* cache the most-recently requested time conversions. This helps when we
* have multiple clocks showing the same time (e.g. the transport frame) */
CONFIG_VARIABLE (bool, external_sync, "external-sync", false)
CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", JACK)
CONFIG_VARIABLE (InsertMergePolicy, insert_merge_policy, "insert-merge-policy", InsertMergeReject)
+CONFIG_VARIABLE (framecnt_t, timecode_offset, "timecode-offset", 0)
+CONFIG_VARIABLE (bool, timecode_offset_negative, "timecode-offset-negative", true)
PBD::Signal0<void> Session::SendFeedback;
PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
-PBD::Signal0<void> Session::TimecodeOffsetChanged;
PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
PBD::Signal0<void> Session::AutoBindingOn;
}
last_timecode_when = 0;
- _timecode_offset = 0;
- _timecode_offset_negative = true;
last_timecode_valid = false;
sync_time_vars ();
listen_position_changed ();
} else if (p == "solo-control-is-listen-control") {
solo_control_mode_changed ();
+ } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
+ last_timecode_valid = false;
}
-
set_dirty ();
}
};
}
-void
-Session::set_timecode_offset (nframes_t off)
-{
- _timecode_offset = off;
- last_timecode_valid = false;
-
- TimecodeOffsetChanged (); /* EMIT SIGNAL */
-}
-
-void
-Session::set_timecode_offset_negative (bool neg)
-{
- _timecode_offset_negative = neg;
- last_timecode_valid = false;
-
- TimecodeOffsetChanged (); /* EMIT SIGNAL */
-}
-
void
Session::timecode_to_sample( Timecode::Time& timecode, framepos_t& sample, bool use_offset, bool use_subframes ) const
{
}
if (use_offset) {
- if (timecode_offset_negative()) {
- if (sample >= timecode_offset()) {
- sample -= timecode_offset();
+ if (config.get_timecode_offset_negative()) {
+ if (sample >= config.get_timecode_offset()) {
+ sample -= config.get_timecode_offset();
} else {
/* Prevent song-time from becoming negative */
sample = 0;
}
} else {
if (timecode.negative) {
- if (sample <= timecode_offset()) {
- sample = timecode_offset() - sample;
+ if (sample <= config.get_timecode_offset()) {
+ sample = config.get_timecode_offset() - sample;
} else {
sample = 0;
}
} else {
- sample += timecode_offset();
+ sample += config.get_timecode_offset();
}
}
}
offset_sample = sample;
timecode.negative = false;
} else {
- if (_timecode_offset_negative) {
- offset_sample = sample + _timecode_offset;
+ if (config.get_timecode_offset_negative()) {
+ offset_sample = sample + config.get_timecode_offset ();
timecode.negative = false;
} else {
- if (sample < _timecode_offset) {
- offset_sample = (_timecode_offset - sample);
+ if (sample < config.get_timecode_offset()) {
+ offset_sample = (config.get_timecode_offset() - sample);
timecode.negative = true;
} else {
- offset_sample = sample - _timecode_offset;
+ offset_sample = sample - config.get_timecode_offset();
timecode.negative = false;
}
}
#if 0
/* Timecode info */
- pos->timecode_offset = _timecode_offset;
+ pos->timecode_offset = config.get_timecode_offset();
t.timecode_frame_rate = timecode_frames_per_second();
pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
secs += any.timecode.minutes * 60;
secs += any.timecode.seconds;
secs += any.timecode.frames / timecode_frames_per_second();
- if (_timecode_offset_negative)
- {
- return (nframes_t) floor (secs * frame_rate()) - _timecode_offset;
- }
- else
- {
- return (nframes_t) floor (secs * frame_rate()) + _timecode_offset;
+ if (config.get_timecode_offset_negative()) {
+ return (nframes_t) floor (secs * frame_rate()) - config.get_timecode_offset();
+ } else {
+ return (nframes_t) floor (secs * frame_rate()) + config.get_timecode_offset();
}
break;