#include "time_axis_view.h"
#include "editor_drag.h"
#include "editor_cursors.h"
+#include "ui_config.h"
#include "i18n.h"
Editor::initialize_rulers ()
{
ruler_grabbed_widget = 0;
- /* Not really sure why we can't get this right in a cross-platform way,
- but it seems hard.
- */
-#ifdef __APPLE__
- Pango::FontDescription font (ARDOUR_UI::config()->get_SmallerFont());
-#else
- Pango::FontDescription font (ARDOUR_UI::config()->get_SmallFont());
-#endif
+
+ Pango::FontDescription font (UIConfiguration::instance().get_SmallerFont());
+
_timecode_metric = new TimecodeMetric (this);
_bbt_metric = new BBTMetric (this);
_minsec_metric = new MinsecMetric (this);
_samples_metric = new SamplesMetric (this);
-
+
timecode_ruler = new ArdourCanvas::Ruler (_time_markers_group, *_timecode_metric,
ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
timecode_ruler->set_font_description (font);
minsec_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), minsec_ruler, MinsecRulerItem));
bbt_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), bbt_ruler, BBTRulerItem));
samples_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), samples_ruler, SamplesRulerItem));
-
+
visible_timebars = 0; /*this will be changed below */
}
switch (t) {
case MarkerBarItem:
- ruler_items.push_back (MenuElem (_("New location marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, false, false)));
+ ruler_items.push_back (MenuElem (_("New location marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, false)));
ruler_items.push_back (MenuElem (_("Clear all locations"), sigc::mem_fun(*this, &Editor::clear_markers)));
ruler_items.push_back (MenuElem (_("Unhide locations"), sigc::mem_fun(*this, &Editor::unhide_markers)));
- ruler_items.push_back (SeparatorElem ());
break;
+
case RangeMarkerBarItem:
ruler_items.push_back (MenuElem (_("New range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_range), where)));
ruler_items.push_back (MenuElem (_("Clear all ranges"), sigc::mem_fun(*this, &Editor::clear_ranges)));
ruler_items.push_back (MenuElem (_("Unhide ranges"), sigc::mem_fun(*this, &Editor::unhide_ranges)));
- ruler_items.push_back (SeparatorElem ());
-
break;
- case TransportMarkerBarItem:
+ case TransportMarkerBarItem:
+ ruler_items.push_back (MenuElem (_("New Loop range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_loop), where)));
+ ruler_items.push_back (MenuElem (_("New Punch range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_punch), where)));
break;
case CdMarkerBarItem:
// TODO
- ruler_items.push_back (MenuElem (_("New CD track marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, true, false)));
+ ruler_items.push_back (MenuElem (_("New CD track marker"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_marker), where, true)));
break;
-
case TempoBarItem:
ruler_items.push_back (MenuElem (_("New Tempo"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_tempo_event), where)));
break;
break;
case VideoBarItem:
- ruler_items.push_back (MenuElem (_("Timeline height")));
- static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ /* proper headings would be nice
+ * but AFAICT the only way to get them will be to define a
+ * special GTK style for insensitive Elements or subclass MenuItem
+ */
+ //ruler_items.push_back (MenuElem (_("Timeline height"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
ruler_items.push_back (CheckMenuElem (_("Large"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 6)));
if (videotl_bar_height == 6) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Normal"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 4)));
if (videotl_bar_height == 4) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Small"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 3)));
if (videotl_bar_height == 3) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
- ruler_items.push_back (SeparatorElem ());
- ruler_items.push_back (MenuElem (_("Align Video Track")));
- static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ ruler_items.push_back (SeparatorElem ());
+ //ruler_items.push_back (MenuElem (_("Align Video Track"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
ruler_items.push_back (CheckMenuElem (_("Lock")));
{
Gtk::CheckMenuItem* vtl_lock = static_cast<Gtk::CheckMenuItem*>(&ruler_items.back());
vtl_lock->set_active(is_video_timeline_locked());
vtl_lock->signal_activate().connect (sigc::mem_fun(*this, &Editor::toggle_video_timeline_locked));
}
+
+ ruler_items.push_back (SeparatorElem ());
+
+ //ruler_items.push_back (MenuElem (_("Video Monitor"))); // heading
+ //static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
+ ruler_items.push_back (CheckMenuElem (_("Video Monitor")));
+ {
+ Gtk::CheckMenuItem* xjadeo_toggle = static_cast<Gtk::CheckMenuItem*>(&ruler_items.back());
+ if (!ARDOUR_UI::instance()->video_timeline->found_xjadeo()) {
+ xjadeo_toggle->set_sensitive(false);
+ }
+ xjadeo_toggle->set_active(xjadeo_proc_action->get_active());
+ xjadeo_toggle->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &Editor::toggle_xjadeo_proc), -1));
+ }
break;
default:
return;
}
- fr = _session->frame_rate();
+ fr = _session->frame_rate();
if (lower > (spacer = (framepos_t) (128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else if (range <= 8 * 60 * 60 * fr) { /* 4 - 8 hrs*/
timecode_ruler_scale = timecode_show_hours;
timecode_mark_modulo = 1;
- timecode_nmarks = 2 + 8;
+ timecode_nmarks = 2 + 8;
} else if (range <= 16 * 60 * 60 * fr) { /* 16-24 hrs*/
timecode_ruler_scale = timecode_show_hours;
timecode_mark_modulo = 1;
} else {
const framecnt_t hours_in_range = range / (60 * 60 * fr);
- const int text_width_rough_guess = 70; /* pixels, very very approximate guess at how wide the tick mark text is */
+ const int text_width_rough_guess = 120; /* pixels, very very approximate guess at how wide the tick mark text is */
/* Normally we do not need to know anything about the width of the canvas
to set the ruler scale, because the caller has already determined
But in this case, where the range defined by lower and uppper can vary
substantially (basically anything from 24hrs+ to several billion years)
- trying to decide which tick marks to show does require us to know
+ trying to decide which tick marks to show does require us to know
about the available width.
*/
switch (timecode_ruler_scale) {
case timecode_show_bits:
-
// Find timecode time of this sample (pos) with subframe accuracy
_session->sample_to_timecode(pos, timecode, true /* use_offset */, true /* use_subframes */ );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, true /* use_subframes */ );
if ((timecode.subframes % timecode_mark_modulo) == 0) {
if (timecode.subframes == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
-
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), ".%02u", timecode.subframes);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
-
marks.push_back (mark);
-
// Increment subframes by one
Timecode::increment_subframes( timecode, _session->config.get_subframes_per_frame() );
}
- break;
+ break;
+
+ case timecode_show_frames:
+ // Find timecode time of this sample (pos)
+ _session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
+ // Go to next whole frame down
+ Timecode::frames_floor( timecode );
+ for (n = 0; n < timecode_nmarks; n++) {
+ _session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
+ if ((timecode.frames % timecode_mark_modulo) == 0) {
+ if (timecode.frames == 0) {
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ } else {
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ }
+ mark.position = pos;
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
+ } else {
+ snprintf (buf, sizeof(buf)," ");
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ mark.position = pos;
+ }
+ mark.label = buf;
+ marks.push_back (mark);
+ Timecode::increment( timecode, _session->config.get_subframes_per_frame() );
+ }
+ break;
+
case timecode_show_seconds:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole second down
Timecode::seconds_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.seconds % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
mark.position = pos;
}
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
mark.position = pos;
-
}
mark.label = buf;
marks.push_back (mark);
-
Timecode::increment_seconds( timecode, _session->config.get_subframes_per_frame() );
}
- break;
+ break;
+
case timecode_show_minutes:
- // Find timecode time of this sample (pos)
+ //Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole minute down
Timecode::minutes_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.minutes % timecode_mark_modulo) == 0) {
} else {
mark.style = ArdourCanvas::Ruler::Mark::Minor;
}
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
Timecode::increment_minutes( timecode, _session->config.get_subframes_per_frame() );
}
-
- break;
+ break;
case timecode_show_hours:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
// Go to next whole hour down
Timecode::hours_floor( timecode );
-
for (n = 0; n < timecode_nmarks; n++) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.hours % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
mark.style = ArdourCanvas::Ruler::Mark::Micro;
-
}
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
- /* Move to next hour */
- Timecode::increment_hours( timecode, _session->config.get_subframes_per_frame() );
+ Timecode::increment_hours( timecode, _session->config.get_subframes_per_frame() );
}
- break;
-
+ break;
case timecode_show_many_hours:
// Find timecode time of this sample (pos)
_session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
if ((timecode.hours % timecode_mark_modulo) == 0) {
mark.style = ArdourCanvas::Ruler::Mark::Major;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
+ snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
mark.label = buf;
mark.position = pos;
marks.push_back (mark);
++n;
- }
+ }
/* can't use Timecode::increment_hours() here because we may be traversing thousands of hours
and doing it 1 hour at a time is just stupid (and slow).
*/
timecode.hours += timecode_mark_modulo;
}
- break;
-
- case timecode_show_frames:
- // Find timecode time of this sample (pos)
- _session->sample_to_timecode(pos, timecode, true /* use_offset */, false /* use_subframes */ );
- // Go to next whole frame down
- Timecode::frames_floor( timecode );
-
- for (n = 0; n < timecode_nmarks; n++) {
- _session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
- if ((timecode.frames % timecode_mark_modulo) == 0) {
- if (timecode.frames == 0) {
- mark.style = ArdourCanvas::Ruler::Mark::Major;
- } else {
- mark.style = ArdourCanvas::Ruler::Mark::Minor;
- }
- mark.position = pos;
- if (timecode.hours) {
- snprintf (buf, sizeof(buf), "%s%u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds);
- } else {
- snprintf (buf, sizeof(buf), "%s%u:%02u", timecode.negative ? "-" : "", timecode.minutes, timecode.seconds);
- }
- } else {
- snprintf (buf, sizeof(buf)," ");
- mark.style = ArdourCanvas::Ruler::Mark::Micro;
- mark.position = pos;
-
- }
- mark.label = buf;
- marks.push_back (mark);
- Timecode::increment( timecode, _session->config.get_subframes_per_frame() );
- }
-
- break;
+ break;
}
}
-
-
void
Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper,
ARDOUR::TempoMap::BBTPointList::const_iterator begin,
} else {
bbt_ruler_scale = bbt_show_ticks_detail;
}
-
+
if ((bbt_ruler_scale == bbt_show_ticks_detail) && (lower_beat.beats == upper_beat.beats) && (upper_beat.ticks - lower_beat.ticks <= Timecode::BBT_Time::ticks_per_beat / 4)) {
bbt_ruler_scale = bbt_show_ticks_super_detail;
}
}
-static void
+static void
edit_last_mark_label (std::vector<ArdourCanvas::Ruler::Mark>& marks, const std::string& newlabel)
{
ArdourCanvas::Ruler::Mark copy = marks.back();
copy.label = newlabel;
marks.pop_back ();
marks.push_back (copy);
-}
+}
void
Editor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble lower, gdouble upper, gint /*maxchars*/)
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
-
+
// could do marks.assign() here to preallocate
mark.label = "";
But in this case, where the range defined by lower and uppper can vary
substantially (anything from 24hrs+ to several billion years)
- trying to decide which tick marks to show does require us to know
+ trying to decide which tick marks to show does require us to know
about the available width.
*/
marks.push_back (mark);
}
break;
-
+
case minsec_show_seconds:
for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
marks.push_back (mark);
}
break;
-
+
case minsec_show_many_hours:
for (n = 0; n < minsec_nmarks; ) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);