#include <gtk/gtkaction.h>
-#include "canvas/group.h"
+#include "canvas/container.h"
+#include "canvas/canvas.h"
+#include "canvas/ruler.h"
+#include "canvas/debug.h"
+#include "canvas/scroll_group.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour/profile.h"
#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/keyboard.h"
+#include "ardour_ui.h"
#include "editor.h"
#include "editing.h"
#include "actions.h"
-#include "gtk-custom-hruler.h"
#include "gui_thread.h"
+#include "ruler_dialog.h"
#include "time_axis_view.h"
#include "editor_drag.h"
#include "editor_cursors.h"
using namespace Gtk;
using namespace Editing;
-Editor *Editor::ruler_editor;
-
/* the order here must match the "metric" enums in editor.h */
-GtkCustomMetric Editor::ruler_metrics[4] = {
- {1, Editor::_metric_get_timecode },
- {1, Editor::_metric_get_bbt },
- {1, Editor::_metric_get_samples },
- {1, Editor::_metric_get_minsec }
-};
-
-void
-Editor::initialize_rulers ()
+class TimecodeMetric : public ArdourCanvas::Ruler::Metric
{
- ruler_editor = this;
- ruler_grabbed_widget = 0;
-
- _ruler_separator = new Gtk::HSeparator();
- _ruler_separator->set_size_request(-1, 2);
- _ruler_separator->set_name("TimebarPadding");
- _ruler_separator->show();
-
- _minsec_ruler = gtk_custom_hruler_new ();
- minsec_ruler = Glib::wrap (_minsec_ruler);
- minsec_ruler->set_name ("MinSecRuler");
- minsec_ruler->set_size_request (-1, (int)timebar_height);
- gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_minsec_ruler), &ruler_metrics[ruler_metric_minsec]);
- minsec_ruler->hide ();
- minsec_ruler->set_no_show_all();
-
- _timecode_ruler = gtk_custom_hruler_new ();
- timecode_ruler = Glib::wrap (_timecode_ruler);
- timecode_ruler->set_name ("TimecodeRuler");
- timecode_ruler->set_size_request (-1, (int)timebar_height);
- gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_timecode_ruler), &ruler_metrics[ruler_metric_timecode]);
- timecode_ruler->hide ();
- timecode_ruler->set_no_show_all();
- timecode_nmarks = 0;
-
- _bbt_ruler = gtk_custom_hruler_new ();
- bbt_ruler = Glib::wrap (_bbt_ruler);
- bbt_ruler->set_name ("BBTRuler");
- bbt_ruler->set_size_request (-1, (int)timebar_height);
- gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_bbt_ruler), &ruler_metrics[ruler_metric_bbt]);
- bbt_ruler->hide ();
- bbt_ruler->set_no_show_all();
- bbt_nmarks = 0;
-
- _samples_ruler = gtk_custom_hruler_new ();
- samples_ruler = Glib::wrap (_samples_ruler);
- samples_ruler->set_name ("SamplesRuler");
- samples_ruler->set_size_request (-1, (int) timebar_height);
- gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER (_samples_ruler), &ruler_metrics[ruler_metric_samples]);
- samples_ruler->hide ();
- samples_ruler->set_no_show_all ();
-
- _bbt_ruler = gtk_custom_hruler_new ();
- bbt_ruler = Glib::wrap (_bbt_ruler);
- bbt_ruler->set_name ("BBTRuler");
- bbt_ruler->set_size_request (-1, (int)timebar_height);
- gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_bbt_ruler), &ruler_metrics[ruler_metric_bbt]);
- bbt_ruler->hide ();
- bbt_ruler->set_no_show_all();
- minsec_ruler->hide ();
- minsec_ruler->set_no_show_all();
- minsec_nmarks = 0;
-
- using namespace Box_Helpers;
- BoxList & ruler_lab_children = ruler_label_vbox.children();
- BoxList & ruler_children = time_canvas_vbox.children();
- BoxList & lab_children = time_bars_vbox.children();
-
- BoxList::iterator canvaspos = ruler_children.begin();
-
- lab_children.push_back (Element(meter_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(tempo_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(range_mark_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(transport_mark_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
- lab_children.push_back (Element(videotl_label, PACK_SHRINK, PACK_START));
+ public:
+ TimecodeMetric (Editor* e) : _editor (e) {}
- ruler_lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START));
- ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START));
- ruler_lab_children.push_back (Element(timecode_label, PACK_SHRINK, PACK_START));
- ruler_children.insert (canvaspos, Element(*timecode_ruler, PACK_SHRINK, PACK_START));
- ruler_lab_children.push_back (Element(samples_label, PACK_SHRINK, PACK_START));
- ruler_children.insert (canvaspos, Element (*samples_ruler, PACK_SHRINK, PACK_START));
- ruler_lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START));
- ruler_children.insert (canvaspos, Element(*bbt_ruler, PACK_SHRINK, PACK_START));
-
- timecode_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
- bbt_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
- samples_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
- minsec_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
-
- timecode_ruler->signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_release));
- bbt_ruler->signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_release));
- samples_ruler->signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_release));
- minsec_ruler->signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_release));
-
- timecode_ruler->signal_button_press_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_press));
- bbt_ruler->signal_button_press_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_press));
- samples_ruler->signal_button_press_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_press));
- minsec_ruler->signal_button_press_event().connect (sigc::mem_fun(*this, &Editor::ruler_button_press));
-
- timecode_ruler->signal_motion_notify_event().connect (sigc::mem_fun(*this, &Editor::ruler_mouse_motion));
- bbt_ruler->signal_motion_notify_event().connect (sigc::mem_fun(*this, &Editor::ruler_mouse_motion));
- samples_ruler->signal_motion_notify_event().connect (sigc::mem_fun(*this, &Editor::ruler_mouse_motion));
- minsec_ruler->signal_motion_notify_event().connect (sigc::mem_fun(*this, &Editor::ruler_mouse_motion));
-
- timecode_ruler->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::ruler_scroll));
- bbt_ruler->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::ruler_scroll));
- samples_ruler->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::ruler_scroll));
- minsec_ruler->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::ruler_scroll));
+ void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, double lower, double upper, int maxchars) const {
+ _editor->metric_get_timecode (marks, lower, upper, maxchars);
+ }
- visible_timebars = 0; /*this will be changed below */
-}
+ private:
+ Editor* _editor;
+};
-bool
-Editor::ruler_scroll (GdkEventScroll* event)
+class SamplesMetric : public ArdourCanvas::Ruler::Metric
{
- framepos_t xdelta;
- int direction = event->direction;
- bool handled = false;
-
- switch (direction) {
- case GDK_SCROLL_UP:
- temporal_zoom_step (false);
- handled = true;
- break;
-
- case GDK_SCROLL_DOWN:
- temporal_zoom_step (true);
- handled = true;
- break;
+ public:
+ SamplesMetric (Editor* e) : _editor (e) {}
- case GDK_SCROLL_LEFT:
- xdelta = (current_page_samples() / 2);
- if (leftmost_frame > xdelta) {
- reset_x_origin (leftmost_frame - xdelta);
- } else {
- reset_x_origin (0);
- }
- handled = true;
- break;
-
- case GDK_SCROLL_RIGHT:
- xdelta = (current_page_samples() / 2);
- if (max_framepos - xdelta > leftmost_frame) {
- reset_x_origin (leftmost_frame + xdelta);
- } else {
- reset_x_origin (max_framepos - current_page_samples());
- }
- handled = true;
- break;
-
- default:
- /* what? */
- break;
+ void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, double lower, double upper, int maxchars) const {
+ _editor->metric_get_samples (marks, lower, upper, maxchars);
}
- return handled;
-}
-
+ private:
+ Editor* _editor;
+};
-bool
-Editor::ruler_button_press (GdkEventButton* ev)
+class BBTMetric : public ArdourCanvas::Ruler::Metric
{
- if (_session == 0) {
- return false;
- }
-
- Widget * grab_widget = 0;
+ public:
+ BBTMetric (Editor* e) : _editor (e) {}
- if (timecode_ruler->is_realized() && ev->window == timecode_ruler->get_window()->gobj()) {
- grab_widget = timecode_ruler;
- } else if (bbt_ruler->is_realized() && ev->window == bbt_ruler->get_window()->gobj()) {
- grab_widget = bbt_ruler;
- } else if (samples_ruler->is_realized() && ev->window == samples_ruler->get_window()->gobj()) {
- grab_widget = samples_ruler;
- } else if (minsec_ruler->is_realized() && ev->window == minsec_ruler->get_window()->gobj()) {
- grab_widget = minsec_ruler;
+ void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, double lower, double upper, int maxchars) const {
+ _editor->metric_get_bbt (marks, lower, upper, maxchars);
}
- if (grab_widget) {
- grab_widget->add_modal_grab ();
- ruler_grabbed_widget = grab_widget;
- }
+ private:
+ Editor* _editor;
+};
- if (ev->button == 1) {
- // Since we will locate the playhead on button release, cancel any running
- // auditions.
- if (_session->is_auditioning()) {
- _session->cancel_audition ();
- }
+class MinsecMetric : public ArdourCanvas::Ruler::Metric
+{
+ public:
+ MinsecMetric (Editor* e) : _editor (e) {}
- /* playhead cursor */
- _drags->set (new CursorDrag (this, *playhead_cursor, false), reinterpret_cast<GdkEvent *> (ev));
- _dragging_playhead = true;
+ void get_marks (std::vector<ArdourCanvas::Ruler::Mark>& marks, double lower, double upper, int maxchars) const {
+ _editor->metric_get_minsec (marks, lower, upper, maxchars);
}
- return true;
-}
+ private:
+ Editor* _editor;
+};
-bool
-Editor::ruler_button_release (GdkEventButton* ev)
+static ArdourCanvas::Ruler::Metric* _bbt_metric;
+static ArdourCanvas::Ruler::Metric* _timecode_metric;
+static ArdourCanvas::Ruler::Metric* _samples_metric;
+static ArdourCanvas::Ruler::Metric* _minsec_metric;
+
+void
+Editor::initialize_rulers ()
{
- if (_session == 0) {
- return false;
- }
+ ruler_grabbed_widget = 0;
- gint x,y;
- Gdk::ModifierType state;
+ Pango::FontDescription font (ARDOUR_UI::config()->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);
+ CANVAS_DEBUG_NAME (timecode_ruler, "timecode ruler");
+ timecode_nmarks = 0;
- if (_drags->active ()) {
- _drags->end_grab (reinterpret_cast<GdkEvent*> (ev));
- _dragging_playhead = false;
- }
+ samples_ruler = new ArdourCanvas::Ruler (_time_markers_group, *_samples_metric,
+ ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
+ samples_ruler->set_font_description (font);
+ CANVAS_DEBUG_NAME (samples_ruler, "samples ruler");
- if (ev->button == 3) {
- /* need to use the correct x,y, the event lies */
- time_canvas_event_box.get_window()->get_pointer (x, y, state);
+ minsec_ruler = new ArdourCanvas::Ruler (_time_markers_group, *_minsec_metric,
+ ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
+ minsec_ruler->set_font_description (font);
+ CANVAS_DEBUG_NAME (minsec_ruler, "minsec ruler");
+ minsec_nmarks = 0;
- stop_canvas_autoscroll();
+ bbt_ruler = new ArdourCanvas::Ruler (_time_markers_group, *_bbt_metric,
+ ArdourCanvas::Rect (0, 0, ArdourCanvas::COORD_MAX, timebar_height));
+ bbt_ruler->set_font_description (font);
+ CANVAS_DEBUG_NAME (bbt_ruler, "bbt ruler");
+ timecode_nmarks = 0;
- framepos_t where = leftmost_frame + pixel_to_sample (x);
- snap_to (where);
- popup_ruler_menu (where);
- }
+ using namespace Box_Helpers;
+ BoxList & lab_children = time_bars_vbox.children();
- if (ruler_grabbed_widget) {
- ruler_grabbed_widget->remove_modal_grab();
- ruler_grabbed_widget = 0;
- }
+ lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(timecode_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(samples_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(meter_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(tempo_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(range_mark_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(transport_mark_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
+ lab_children.push_back (Element(videotl_label, PACK_SHRINK, PACK_START));
- return true;
+ /* 1 event handler to bind them all ... */
+
+ timecode_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), timecode_ruler, TimecodeRulerItem));
+ 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 */
}
bool
Editor::ruler_label_button_release (GdkEventButton* ev)
{
- if (ev->button == 3) {
- Gtk::Menu* m = dynamic_cast<Gtk::Menu*> (ActionManager::get_widget (X_("/RulerMenuPopup")));
- if (m) {
- m->popup (1, ev->time);
+ if (Gtkmm2ext::Keyboard::is_context_menu_event (ev)) {
+ if (!ruler_dialog) {
+ ruler_dialog = new RulerDialog ();
}
+ ruler_dialog->present ();
}
return true;
}
-
-bool
-Editor::ruler_mouse_motion (GdkEventMotion* ev)
-{
- if (_session == 0) {
- return false;
- }
-
- if (_drags->active ()) {
- _drags->motion_handler (reinterpret_cast<GdkEvent*> (ev), false);
- }
-
- return true;
-}
-
-
void
Editor::popup_ruler_menu (framepos_t where, ItemType t)
{
case TempoBarItem:
ruler_items.push_back (MenuElem (_("New Tempo"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_tempo_event), where)));
- ruler_items.push_back (SeparatorElem ());
break;
case MeterBarItem:
ruler_items.push_back (MenuElem (_("New Meter"), sigc::bind ( sigc::mem_fun(*this, &Editor::mouse_add_new_meter_event), where)));
- ruler_items.push_back (SeparatorElem ());
break;
case VideoBarItem:
ruler_items.push_back (MenuElem (_("Timeline height")));
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<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ 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<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ 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<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ 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")));
ruler_items.push_back (CheckMenuElem (_("Lock")));
{
- CheckMenuItem* vtl_lock = static_cast<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));
+ 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 ());
break;
default:
break;
}
- Glib::RefPtr<Action> action;
-
- action = ActionManager::get_action ("Rulers", "toggle-minsec-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- if (!Profile->get_sae()) {
- action = ActionManager::get_action ("Rulers", "toggle-timecode-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- }
- action = ActionManager::get_action ("Rulers", "toggle-samples-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-bbt-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-meter-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-tempo-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- if (!Profile->get_sae()) {
- action = ActionManager::get_action ("Rulers", "toggle-range-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- }
- action = ActionManager::get_action ("Rulers", "toggle-loop-punch-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-cd-marker-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-marker-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
- }
- action = ActionManager::get_action ("Rulers", "toggle-video-ruler");
- if (action) {
- ruler_items.push_back (MenuElem (*action->create_menu_item()));
+ if (!ruler_items.empty()) {
+ editor_ruler_menu->popup (1, gtk_get_current_event_time());
}
- editor_ruler_menu->popup (1, gtk_get_current_event_time());
-
no_ruler_shown_update = false;
}
void
Editor::update_ruler_visibility ()
{
- int visible_rulers = 0;
+ int visible_timebars = 0;
if (no_ruler_shown_update) {
return;
}
- visible_timebars = 0;
+ /* the order of the timebars is fixed, so we have to go through each one
+ * and adjust its position depending on what is shown.
+ *
+ * Order: minsec, timecode, samples, bbt, meter, tempo, ranges,
+ * loop/punch, cd markers, location markers
+ */
+
+ double tbpos = 0.0;
+ double tbgpos = 0.0;
+ double old_unit_pos;
+
+#ifdef GTKOSX
+ /* gtk update probs require this (damn) */
+ meter_label.hide();
+ tempo_label.hide();
+ range_mark_label.hide();
+ transport_mark_label.hide();
+ cd_mark_label.hide();
+ mark_label.hide();
+ videotl_label.hide();
+#endif
if (ruler_minsec_action->get_active()) {
- visible_rulers++;
- minsec_label.show ();
- minsec_ruler->show ();
+ old_unit_pos = minsec_ruler->position().y;
+ if (tbpos != old_unit_pos) {
+ minsec_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
+ }
+ minsec_ruler->show();
+ minsec_label.show();
+ tbpos += timebar_height;
+ tbgpos += timebar_height;
+ visible_timebars++;
} else {
- minsec_label.hide ();
- minsec_ruler->hide ();
+ minsec_ruler->hide();
+ minsec_label.hide();
}
if (ruler_timecode_action->get_active()) {
- visible_rulers++;
- timecode_label.show ();
- timecode_ruler->show ();
+ old_unit_pos = timecode_ruler->position().y;
+ if (tbpos != old_unit_pos) {
+ timecode_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
+ }
+ timecode_ruler->show();
+ timecode_label.show();
+ tbpos += timebar_height;
+ tbgpos += timebar_height;
+ visible_timebars++;
} else {
- timecode_label.hide ();
- timecode_ruler->hide ();
+ timecode_ruler->hide();
+ timecode_label.hide();
}
if (ruler_samples_action->get_active()) {
- visible_rulers++;
- samples_label.show ();
- samples_ruler->show ();
+ old_unit_pos = samples_ruler->position().y;
+ if (tbpos != old_unit_pos) {
+ samples_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
+ }
+ samples_ruler->show();
+ samples_label.show();
+ tbpos += timebar_height;
+ tbgpos += timebar_height;
+ visible_timebars++;
} else {
- samples_label.hide ();
- samples_ruler->hide ();
+ samples_ruler->hide();
+ samples_label.hide();
}
if (ruler_bbt_action->get_active()) {
- visible_rulers++;
- bbt_label.show ();
- bbt_ruler->show ();
+ old_unit_pos = bbt_ruler->position().y;
+ if (tbpos != old_unit_pos) {
+ bbt_ruler->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
+ }
+ bbt_ruler->show();
+ bbt_label.show();
+ tbpos += timebar_height;
+ tbgpos += timebar_height;
+ visible_timebars++;
} else {
- bbt_label.hide ();
- bbt_ruler->hide ();
+ bbt_ruler->hide();
+ bbt_label.hide();
}
- double tbpos = 0.0;
- double tbgpos = 0.0;
- double old_unit_pos;
-
-#ifdef GTKOSX
- /* gtk update probs require this (damn) */
- meter_label.hide();
- tempo_label.hide();
- range_mark_label.hide();
- transport_mark_label.hide();
- cd_mark_label.hide();
- mark_label.hide();
- videotl_label.hide();
-#endif
if (ruler_meter_action->get_active()) {
old_unit_pos = meter_group->position().y;
if (tbpos != old_unit_pos) {
meter_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = meter_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- meter_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- meter_bar_group->show();
meter_group->show();
meter_label.show();
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
} else {
- meter_bar_group->hide();
meter_group->hide();
meter_label.hide();
}
if (tbpos != old_unit_pos) {
tempo_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = tempo_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- tempo_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- tempo_bar_group->show();
tempo_group->show();
tempo_label.show();
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
} else {
- tempo_bar_group->hide();
tempo_group->hide();
tempo_label.hide();
}
if (tbpos != old_unit_pos) {
range_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = range_marker_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- range_marker_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- range_marker_bar_group->show();
range_marker_group->show();
range_mark_label.show();
tbgpos += timebar_height;
visible_timebars++;
} else {
- range_marker_bar_group->hide();
range_marker_group->hide();
range_mark_label.hide();
}
if (tbpos != old_unit_pos) {
transport_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = transport_marker_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- transport_marker_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- transport_marker_bar_group->show();
transport_marker_group->show();
transport_mark_label.show();
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
} else {
- transport_marker_bar_group->hide();
transport_marker_group->hide();
transport_mark_label.hide();
}
if (tbpos != old_unit_pos) {
cd_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = cd_marker_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- cd_marker_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- cd_marker_bar_group->show();
cd_marker_group->show();
cd_mark_label.show();
tbpos += timebar_height;
// make sure all cd markers show up in their respective places
update_cd_marker_display();
} else {
- cd_marker_bar_group->hide();
cd_marker_group->hide();
cd_mark_label.hide();
// make sure all cd markers show up in their respective places
if (tbpos != old_unit_pos) {
marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = marker_bar_group->position().y;
- if (tbgpos != old_unit_pos) {
- marker_bar_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- marker_bar_group->show();
marker_group->show();
mark_label.show();
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
} else {
- marker_bar_group->hide();
marker_group->hide();
mark_label.hide();
}
if (tbpos != old_unit_pos) {
videotl_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
- old_unit_pos = videotl_group->position().y;
- if (tbgpos != old_unit_pos) {
- videotl_group->move (ArdourCanvas::Duple (0.0, tbgpos - old_unit_pos));
- }
- videotl_group->show();
videotl_group->show();
videotl_label.show();
tbpos += timebar_height * videotl_bar_height;
tbgpos += timebar_height * videotl_bar_height;
visible_timebars+=videotl_bar_height;
- queue_visual_videotimeline_update();
+ queue_visual_videotimeline_update();
} else {
- videotl_group->hide();
videotl_group->hide();
videotl_label.hide();
- update_video_timeline(true);
+ update_video_timeline(true);
}
- ruler_label_vbox.set_size_request (-1, (int)(timebar_height * visible_rulers));
- time_canvas_vbox.set_size_request (-1,-1);
+ time_bars_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars));
+
+ /* move hv_scroll_group (trackviews) to the end of the timebars
+ */
+
+ hv_scroll_group->set_y_position (timebar_height * visible_timebars);
compute_fixed_ruler_scale ();
update_fixed_rulers();
framepos_t rightmost_frame = leftmost_frame + current_page_samples();
if (ruler_timecode_action->get_active()) {
- gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_timecode_ruler), leftmost_frame, rightmost_frame,
- leftmost_frame, _session->current_end_frame());
+ timecode_ruler->set_range (leftmost_frame, rightmost_frame);
}
}
compute_fixed_ruler_scale ();
- ruler_metrics[ruler_metric_timecode].units_per_pixel = samples_per_pixel;
- ruler_metrics[ruler_metric_samples].units_per_pixel = samples_per_pixel;
- ruler_metrics[ruler_metric_minsec].units_per_pixel = samples_per_pixel;
+ _timecode_metric->units_per_pixel = samples_per_pixel;
+ _samples_metric->units_per_pixel = samples_per_pixel;
+ _minsec_metric->units_per_pixel = samples_per_pixel;
rightmost_frame = leftmost_frame + current_page_samples();
*/
if (ruler_timecode_action->get_active()) {
- gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_timecode_ruler), leftmost_frame, rightmost_frame,
- leftmost_frame, _session->current_end_frame());
+ timecode_ruler->set_range (leftmost_frame, rightmost_frame);
}
if (ruler_samples_action->get_active()) {
- gtk_custom_ruler_set_range (GTK_CUSTOM_RULER (_samples_ruler), leftmost_frame, rightmost_frame,
- leftmost_frame, _session->current_end_frame());
+ samples_ruler->set_range (leftmost_frame, rightmost_frame);
}
if (ruler_minsec_action->get_active()) {
- gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_minsec_ruler), leftmost_frame, rightmost_frame,
- leftmost_frame, _session->current_end_frame());
+ minsec_ruler->set_range (leftmost_frame, rightmost_frame);
}
}
compute_bbt_ruler_scale (leftmost_frame, leftmost_frame+current_page_samples(),
begin, end);
- ruler_metrics[ruler_metric_bbt].units_per_pixel = samples_per_pixel;
+ _bbt_metric->units_per_pixel = samples_per_pixel;
if (ruler_bbt_action->get_active()) {
- gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_bbt_ruler), leftmost_frame, leftmost_frame+current_page_samples(),
- leftmost_frame, _session->current_end_frame());
+ bbt_ruler->set_range (leftmost_frame, leftmost_frame+current_page_samples());
}
}
-/* Mark generation */
-
-gint
-Editor::_metric_get_timecode (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
-{
- return ruler_editor->metric_get_timecode (marks, lower, upper, maxchars);
-}
-
-gint
-Editor::_metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
-{
- return ruler_editor->metric_get_bbt (marks, lower, upper, maxchars);
-}
-
-gint
-Editor::_metric_get_samples (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
-{
- return ruler_editor->metric_get_samples (marks, lower, upper, maxchars);
-}
-
-gint
-Editor::_metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
-{
- return ruler_editor->metric_get_minsec (marks, lower, upper, maxchars);
-}
void
Editor::set_timecode_ruler_scale (framepos_t lower, framepos_t upper)
{
+ using namespace std;
+
framepos_t spacer;
framepos_t fr;
return;
}
- fr = _session->frame_rate();
+ fr = _session->frame_rate();
if (lower > (spacer = (framepos_t) (128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else {
lower = 0;
}
+
upper = upper + spacer;
framecnt_t const range = upper - lower;
} 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;
timecode_nmarks = 2 + 24;
} else {
- /* not possible if framepos_t is a 32 bit quantity */
+ const framecnt_t hours_in_range = range / (60 * 60 * fr);
+ const int text_width_rough_guess = 120; /* pixels, very very approximate guess at how wide the tick mark text is */
- timecode_ruler_scale = timecode_show_hours;
- timecode_mark_modulo = 4;
- timecode_nmarks = 2 + 24;
- }
+ /* 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
+ the width and set lower + upper arguments to this function to match that.
+ 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
+ about the available width.
+ */
+
+ timecode_nmarks = _track_canvas->width() / text_width_rough_guess;
+ timecode_ruler_scale = timecode_show_many_hours;
+ timecode_mark_modulo = max ((framecnt_t) 1, 1 + (hours_in_range / timecode_nmarks));
+ }
}
-gint
-Editor::metric_get_timecode (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upper*/, gint /*maxchars*/)
+void
+Editor::metric_get_timecode (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble lower, gdouble /*upper*/, gint /*maxchars*/)
{
framepos_t pos;
framecnt_t spacer;
Timecode::Time timecode;
gchar buf[16];
gint n;
+ ArdourCanvas::Ruler::Mark mark;
if (_session == 0) {
- return 0;
+ return;
}
if (lower > (spacer = (framecnt_t)(128 * Editor::get_current_zoom ()))) {
pos = (framecnt_t) floor (lower);
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * timecode_nmarks);
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) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), ".%02u", timecode.subframes);
}
} else {
snprintf (buf, sizeof(buf)," ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
-
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
-
+ 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) {
if (timecode.seconds == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- (*marks)[n].position = pos;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ mark.position = pos;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- (*marks)[n].position = pos;
+ 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)," ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- (*marks)[n].position = pos;
-
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ mark.position = pos;
}
- (*marks)[n].label = g_strdup (buf);
+ 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) {
if (timecode.minutes == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
}
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
-
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
-
+ 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) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
} else {
snprintf (buf, sizeof(buf)," ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
-
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
-
+ mark.label = buf;
+ mark.position = pos;
+ marks.push_back (mark);
Timecode::increment_hours( timecode, _session->config.get_subframes_per_frame() );
}
- break;
- case timecode_show_frames:
+ 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 */ );
- // Go to next whole frame down
- Timecode::frames_floor( timecode );
+ // Go to next whole hour down
+ Timecode::hours_floor (timecode);
- for (n = 0; n < timecode_nmarks; n++) {
+ for (n = 0; n < timecode_nmarks; ) {
_session->timecode_to_sample(timecode, pos, true /* use_offset */, false /* use_subframes */ );
- if ((timecode.frames % timecode_mark_modulo) == 0) {
- if (timecode.frames == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- }
- (*marks)[n].position = pos;
+ if ((timecode.hours % timecode_mark_modulo) == 0) {
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%s%02u:%02u:%02u:%02u", timecode.negative ? "-" : "", timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
- } else {
- snprintf (buf, sizeof(buf)," ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- (*marks)[n].position = pos;
-
- }
- (*marks)[n].label = g_strdup (buf);
- Timecode::increment( timecode, _session->config.get_subframes_per_frame() );
+ 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;
+ break;
}
-
- return timecode_nmarks;
}
-
void
Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper,
ARDOUR::TempoMap::BBTPointList::const_iterator begin,
bbt_bars = 0;
bbt_nmarks = 1;
- bbt_ruler_scale = bbt_over;
+ bbt_ruler_scale = bbt_show_many;
switch (_snap_type) {
case SnapToBeatDiv2:
}
if (bbt_bars > 8192) {
- bbt_ruler_scale = bbt_over;
+ bbt_ruler_scale = bbt_show_many;
} else if (bbt_bars > 1024) {
bbt_ruler_scale = bbt_show_64;
} else if (bbt_bars > 256) {
} 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;
}
}
-gint
-Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint /*maxchars*/)
+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*/)
{
if (_session == 0) {
- return 0;
+ return;
}
TempoMap::BBTPointList::const_iterator i;
Timecode::BBT_Time next_beat;
framepos_t next_beat_pos;
uint32_t beats = 0;
-
uint32_t tick = 0;
uint32_t skip;
uint32_t t;
double accumulated_error;
bool i_am_accented = false;
bool helper_active = false;
+ ArdourCanvas::Ruler::Mark mark;
ARDOUR::TempoMap::BBTPointList::const_iterator begin;
ARDOUR::TempoMap::BBTPointList::const_iterator end;
compute_current_bbt_points (lower, upper, begin, end);
if (distance (begin, end) == 0) {
- return 0;
+ return;
}
switch (bbt_ruler_scale) {
beats = distance (begin, end);
bbt_nmarks = beats + 2;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+ mark.label = "";
+ mark.position = lower;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ marks.push_back (mark);
- (*marks)[0].label = g_strdup(" ");
- (*marks)[0].position = lower;
- (*marks)[0].style = GtkCustomRulerMarkMicro;
-
for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
- (*marks)[0].label = g_strdup (buf);
+ edit_last_mark_label (marks, buf);
helper_active = true;
} else {
if ((*i).is_bar()) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
} else if (((*i).beat % 2 == 1)) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- snprintf (buf, sizeof(buf), " ");
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ buf[0] = '\0';
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- snprintf (buf, sizeof(buf), " ");
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
n++;
}
}
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
+
+ // could do marks.assign() here to preallocate
- (*marks)[0].label = g_strdup(" ");
- (*marks)[0].position = lower;
- (*marks)[0].style = GtkCustomRulerMarkMicro;
+ mark.label = "";
+ mark.position = lower;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ marks.push_back (mark);
for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
- (*marks)[0].label = g_strdup (buf);
+ edit_last_mark_label (marks, buf);
helper_active = true;
} else {
if ((*i).is_bar()) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
}
if (((*i).frame < bbt_position_of_helper) && helper_active) {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
n++;
}
i_am_accented = true;
}
- snprintf (buf, sizeof(buf), " ");
- (*marks)[n].label = g_strdup (buf);
+ mark.label = "";
/* Error compensation for float to framepos_t*/
accumulated_error += frame_skip_error;
accumulated_error -= 1.0f;
}
- (*marks)[n].position = pos;
+ mark.position = pos;
if ((bbt_beat_subdivision > 4) && i_am_accented) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
i_am_accented = false;
+ marks.push_back (mark);
n++;
}
}
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
- (*marks)[0].label = g_strdup(" ");
- (*marks)[0].position = lower;
- (*marks)[0].style = GtkCustomRulerMarkMicro;
+ mark.label = "";
+ mark.position = lower;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ marks.push_back (mark);
for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
- (*marks)[0].label = g_strdup (buf);
+ edit_last_mark_label (marks, buf);
helper_active = true;
} else {
if ((*i).is_bar()) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
}
if (((*i).frame < bbt_position_of_helper) && helper_active) {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
n++;
}
if (i_am_accented && (pos > bbt_position_of_helper)){
snprintf (buf, sizeof(buf), "%" PRIu32, tick);
} else {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
+ mark.label = buf;
/* Error compensation for float to framepos_t*/
accumulated_error += frame_skip_error;
accumulated_error -= 1.0f;
}
- (*marks)[n].position = pos;
+ mark.position = pos;
if ((bbt_beat_subdivision > 4) && i_am_accented) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
i_am_accented = false;
n++;
bbt_nmarks = (beats + 2) * bbt_beat_subdivision;
bbt_position_of_helper = lower + (30 * Editor::get_current_zoom ());
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
- (*marks)[0].label = g_strdup(" ");
- (*marks)[0].position = lower;
- (*marks)[0].style = GtkCustomRulerMarkMicro;
+ mark.label = "";
+ mark.position = lower;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ marks.push_back (mark);
for (n = 1, i = begin; n < bbt_nmarks && i != end; ++i) {
if ((*i).frame < lower && (bbt_bar_helper_on)) {
snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
- (*marks)[0].label = g_strdup (buf);
+ edit_last_mark_label (marks, buf);
helper_active = true;
} else {
if ((*i).is_bar()) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).beat);
}
if (((*i).frame < bbt_position_of_helper) && helper_active) {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
n++;
}
if (pos > bbt_position_of_helper) {
snprintf (buf, sizeof(buf), "%" PRIu32, tick);
} else {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
}
- (*marks)[n].label = g_strdup (buf);
+ mark.label = buf;
/* Error compensation for float to framepos_t*/
accumulated_error += frame_skip_error;
accumulated_error -= 1.0f;
}
- (*marks)[n].position = pos;
+ mark.position = pos;
if ((bbt_beat_subdivision > 4) && i_am_accented) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
i_am_accented = false;
+ marks.push_back (mark);
n++;
}
}
break;
- case bbt_over:
- bbt_nmarks = 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
- snprintf (buf, sizeof(buf), "cannot handle %" PRIu32 " bars", bbt_bars );
- (*marks)[0].style = GtkCustomRulerMarkMajor;
- (*marks)[0].label = g_strdup (buf);
- (*marks)[0].position = lower;
- n = 1;
-
- break;
+ case bbt_show_many:
+ bbt_nmarks = 1;
+ snprintf (buf, sizeof(buf), "cannot handle %" PRIu32 " bars", bbt_bars );
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ mark.label = buf;
+ mark.position = lower;
+ marks.push_back (mark);
+ break;
case bbt_show_64:
bbt_nmarks = (gint) (bbt_bars / 64) + 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
for (n = 0, i = begin; i != end && n < bbt_nmarks; i++) {
if ((*i).is_bar()) {
if ((*i).bar % 64 == 1) {
if ((*i).bar % 256 == 1) {
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
if ((*i).bar % 256 == 129) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
+ ++n;
}
}
}
case bbt_show_16:
bbt_nmarks = (bbt_bars / 16) + 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
for (n = 0, i = begin; i != end && n < bbt_nmarks; i++) {
if ((*i).is_bar()) {
if ((*i).bar % 16 == 1) {
if ((*i).bar % 64 == 1) {
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
if ((*i).bar % 64 == 33) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
+ ++n;
}
}
}
case bbt_show_4:
bbt_nmarks = (bbt_bars / 4) + 1;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks);
for (n = 0, i = begin; i != end && n < bbt_nmarks; ++i) {
if ((*i).is_bar()) {
if ((*i).bar % 4 == 1) {
if ((*i).bar % 16 == 1) {
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- snprintf (buf, sizeof(buf), " ");
+ buf[0] = '\0';
if ((*i).bar % 16 == 9) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
+ ++n;
}
}
}
break;
case bbt_show_1:
- // default:
+// default:
bbt_nmarks = bbt_bars + 2;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * bbt_nmarks );
- for (n = 0, i = begin; i != end && n < bbt_nmarks; i++) {
+ for (n = 0, i = begin; i != end && n < bbt_nmarks; ++i) {
if ((*i).is_bar()) {
if ((*i).bar % 4 == 1) {
snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- snprintf (buf, sizeof(buf), " ");
- if ((*i).bar % 4 == 3) {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
+ buf[0] = '\0';
+ if ((*i).bar % 4 == 3) {
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ } else {
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ }
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = (*i).frame;
- n++;
+ mark.label = buf;
+ mark.position = (*i).frame;
+ marks.push_back (mark);
+ ++n;
}
}
-
- break;
+ break;
}
-
- return n; //return the actual number of marks made, since we might have skipped some from fractional time signatures
-
}
void
_samples_ruler_interval = (upper - lower) / 5;
}
-gint
-Editor::metric_get_samples (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upper*/, gint /*maxchars*/)
+void
+Editor::metric_get_samples (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble lower, gdouble /*upper*/, gint /*maxchars*/)
{
framepos_t pos;
framepos_t const ilower = (framepos_t) floor (lower);
gchar buf[16];
gint nmarks;
gint n;
+ ArdourCanvas::Ruler::Mark mark;
if (_session == 0) {
- return 0;
+ return;
}
nmarks = 5;
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
for (n = 0, pos = ilower; n < nmarks; pos += _samples_ruler_interval, ++n) {
snprintf (buf, sizeof(buf), "%" PRIi64, pos);
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.label = buf;
+ mark.position = pos;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ marks.push_back (mark);
}
-
- return nmarks;
}
static void
long millisecs;
left = sample;
- hrs = left / (sample_rate * 60 * 60);
- left -= hrs * sample_rate * 60 * 60;
- mins = left / (sample_rate * 60);
- left -= mins * sample_rate * 60;
- secs = left / sample_rate;
- left -= secs * sample_rate;
- millisecs = left * 1000 / sample_rate;
+ hrs = left / (sample_rate * 60 * 60 * 1000);
+ left -= hrs * sample_rate * 60 * 60 * 1000;
+ mins = left / (sample_rate * 60 * 1000);
+ left -= mins * sample_rate * 60 * 1000;
+ secs = left / (sample_rate * 1000);
+ left -= secs * sample_rate * 1000;
+ millisecs = left / sample_rate;
*millisecs_p = millisecs;
*secs_p = secs;
void
Editor::set_minsec_ruler_scale (framepos_t lower, framepos_t upper)
{
- framepos_t fr;
+ framepos_t fr = _session->frame_rate() * 1000;
framepos_t spacer;
if (_session == 0) {
return;
}
- fr = _session->frame_rate();
/* to prevent 'flashing' */
if (lower > (spacer = (framepos_t)(128 * Editor::get_current_zoom ()))) {
lower = 0;
}
upper += spacer;
- framecnt_t const range = upper - lower;
+ framecnt_t const range = (upper - lower) * 1000;
- if (range < (fr / 50)) {
- minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
- minsec_ruler_scale = minsec_show_frames;
- minsec_mark_modulo = 10;
- } else if (range <= (fr / 10)) { /* 0-0.1 second */
+ if (range <= (fr / 10)) { /* 0-0.1 second */
minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
- minsec_ruler_scale = minsec_show_frames;
+ minsec_ruler_scale = minsec_show_msecs;
minsec_mark_modulo = 10;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= (fr / 2)) { /* 0-0.5 second */
minsec_mark_interval = fr / 100; /* show 1/100 seconds */
- minsec_ruler_scale = minsec_show_frames;
+ minsec_ruler_scale = minsec_show_msecs;
minsec_mark_modulo = 100;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= fr) { /* 0-1 second */
minsec_mark_interval = fr / 10; /* show 1/10 seconds */
- minsec_ruler_scale = minsec_show_frames;
+ minsec_ruler_scale = minsec_show_msecs;
minsec_mark_modulo = 200;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 2 * fr) { /* 1-2 seconds */
minsec_mark_interval = fr / 10; /* show 1/10 seconds */
- minsec_ruler_scale = minsec_show_frames;
+ minsec_ruler_scale = minsec_show_msecs;
minsec_mark_modulo = 500;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 8 * fr) { /* 2-5 seconds */
minsec_mark_interval = fr / 5; /* show 2 seconds */
- minsec_ruler_scale = minsec_show_frames;
+ minsec_ruler_scale = minsec_show_msecs;
minsec_mark_modulo = 1000;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 16 * fr) { /* 8-16 seconds */
minsec_mark_interval = fr; /* show 1 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 2;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 30 * fr) { /* 10-30 seconds */
minsec_mark_interval = fr; /* show 1 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 5;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 60 * fr) { /* 30-60 seconds */
minsec_mark_interval = fr; /* show 1 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 5;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 2 * 60 * fr) { /* 1-2 minutes */
minsec_mark_interval = 5 * fr; /* show 5 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 3;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 4 * 60 * fr) { /* 4 minutes */
minsec_mark_interval = 5 * fr; /* show 10 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 30;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 10 * 60 * fr) { /* 10 minutes */
minsec_mark_interval = 30 * fr; /* show 30 seconds */
minsec_ruler_scale = minsec_show_seconds;
minsec_mark_modulo = 120;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 30 * 60 * fr) { /* 10-30 minutes */
minsec_mark_interval = 60 * fr; /* show 1 minute */
minsec_ruler_scale = minsec_show_minutes;
minsec_mark_modulo = 5;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 60 * 60 * fr) { /* 30 minutes - 1hr */
minsec_mark_interval = 2 * 60 * fr; /* show 2 minutes */
minsec_ruler_scale = minsec_show_minutes;
minsec_mark_modulo = 10;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 4 * 60 * 60 * fr) { /* 1 - 4 hrs*/
minsec_mark_interval = 5 * 60 * fr; /* show 10 minutes */
minsec_ruler_scale = minsec_show_minutes;
minsec_mark_modulo = 30;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 8 * 60 * 60 * fr) { /* 4 - 8 hrs*/
minsec_mark_interval = 20 * 60 * fr; /* show 20 minutes */
minsec_ruler_scale = minsec_show_minutes;
minsec_mark_modulo = 60;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else if (range <= 16 * 60 * 60 * fr) { /* 16-24 hrs*/
minsec_mark_interval = 60 * 60 * fr; /* show 60 minutes */
minsec_ruler_scale = minsec_show_hours;
minsec_mark_modulo = 2;
+ minsec_nmarks = 2 + (range / minsec_mark_interval);
} else {
- /* not possible if framepos_t is a 32 bit quantity */
+ 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 */
+
+ /* 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
+ the width and set lower + upper arguments to this function to match that.
- minsec_mark_interval = 4 * 60 * 60 * fr; /* show 4 hrs */
+ 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
+ about the available width.
+ */
+
+ minsec_nmarks = _track_canvas->width() / text_width_rough_guess;
+ minsec_mark_modulo = max ((framecnt_t) 1, 1 + (hours_in_range / minsec_nmarks));
+ minsec_mark_interval = minsec_mark_modulo * (60 * 60 * fr);
+ minsec_ruler_scale = minsec_show_many_hours;
}
- minsec_nmarks = 2 + (range / minsec_mark_interval);
}
-gint
-Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble /*upper*/, gint /*maxchars*/)
+void
+Editor::metric_get_minsec (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdouble lower, gdouble upper, gint /*maxchars*/)
{
framepos_t pos;
framepos_t spacer;
long hrs, mins, secs, millisecs;
gchar buf[16];
gint n;
+ ArdourCanvas::Ruler::Mark mark;
if (_session == 0) {
- return 0;
+ return;
}
/* to prevent 'flashing' */
lower = 0;
}
- *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * minsec_nmarks);
- pos = ((((framepos_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
+ pos = (((1000 * (framepos_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
+
switch (minsec_ruler_scale) {
+
+ case minsec_show_msecs:
+ for (n = 0; n < minsec_nmarks && n < upper; pos += minsec_mark_interval, ++n) {
+ sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
+ if (millisecs % minsec_mark_modulo == 0) {
+ if (millisecs == 0) {
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ } else {
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
+ }
+ snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
+ } else {
+ buf[0] = '\0';
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ }
+ mark.label = buf;
+ mark.position = pos/1000.0;
+ 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);
if (secs % minsec_mark_modulo == 0) {
if (secs == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
}
- snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
+ snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld", hrs, mins, secs);
} else {
- snprintf (buf, sizeof(buf), " ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ buf[0] = '\0';
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
+ mark.label = buf;
+ mark.position = pos/1000.0;
+ marks.push_back (mark);
}
- break;
+ break;
+
case minsec_show_minutes:
for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
if (mins % minsec_mark_modulo == 0) {
if (mins == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
} else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
+ mark.style = ArdourCanvas::Ruler::Mark::Minor;
}
- snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
+ snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld", hrs, mins, secs);
} else {
- snprintf (buf, sizeof(buf), " ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ buf[0] = '\0';
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
+ mark.label = buf;
+ mark.position = pos/1000.0;
+ marks.push_back (mark);
}
- break;
+ break;
+
case minsec_show_hours:
for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
if (hrs % minsec_mark_modulo == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ snprintf (buf, sizeof(buf), "%02ld:%02ld", hrs, mins);
} else {
- snprintf (buf, sizeof(buf), " ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
+ buf[0] = '\0';
+ mark.style = ArdourCanvas::Ruler::Mark::Micro;
+ }
+ mark.label = buf;
+ mark.position = pos/1000.0;
+ 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);
+ if (hrs % minsec_mark_modulo == 0) {
+ mark.style = ArdourCanvas::Ruler::Mark::Major;
+ snprintf (buf, sizeof(buf), "%02ld:00", hrs);
+ mark.label = buf;
+ mark.position = pos/1000.0;
+ marks.push_back (mark);
+ ++n;
}
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
+ pos += minsec_mark_interval;
}
- break;
- case minsec_show_frames:
- for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
- sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
- if (millisecs % minsec_mark_modulo == 0) {
- if (secs == 0) {
- (*marks)[n].style = GtkCustomRulerMarkMajor;
- } else {
- (*marks)[n].style = GtkCustomRulerMarkMinor;
- }
- snprintf (buf, sizeof(buf), "%02ld:%02ld:%02ld.%03ld", hrs, mins, secs, millisecs);
- } else {
- snprintf (buf, sizeof(buf), " ");
- (*marks)[n].style = GtkCustomRulerMarkMicro;
- }
- (*marks)[n].label = g_strdup (buf);
- (*marks)[n].position = pos;
- }
- break;
- }
-
- return minsec_nmarks;
+ break;
+ }
}