From e77b5261d2811a1ad139afc29250e3a3337c455d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 3 Jun 2011 22:18:47 +0000 Subject: next iteration of clock work. still far from complete, and probably waiting on a rethink of text rendering+layout. but it has the info block now, and it semi-works git-svn-id: svn://localhost/ardour2/branches/3.0@9676 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour3_ui_dark.rc.in | 33 ++- gtk2_ardour/ardour_ui.h | 3 + gtk2_ardour/ardour_ui2.cc | 10 + gtk2_ardour/ardour_ui_dialogs.cc | 2 + gtk2_ardour/audio_clock.cc | 601 +++++++++++++++----------------------- gtk2_ardour/audio_clock.h | 80 ++--- gtk2_ardour/time_info_box.cc | 206 +++++++++++++ gtk2_ardour/time_info_box.h | 73 +++++ gtk2_ardour/wscript | 1 + 9 files changed, 597 insertions(+), 412 deletions(-) create mode 100644 gtk2_ardour/time_info_box.cc create mode 100644 gtk2_ardour/time_info_box.h (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in index 2c588d770d..ce5512b36e 100644 --- a/gtk2_ardour/ardour3_ui_dark.rc.in +++ b/gtk2_ardour/ardour3_ui_dark.rc.in @@ -942,7 +942,7 @@ style "recording_big_clock_display" = "non_recording_big_clock_display" style "transport_clock_display" { - font_name = "@FONT_BOLD_BIG@" + font_name = "monospace @FONT_BOLD_BIG@" fg[ACTIVE] = darker(@@COLPREFIX@_bright_indicator) fg[SELECTED] = darker(@@COLPREFIX@_bright_indicator) @@ -989,6 +989,35 @@ style "default_clock_display" = "medium_text" bg[ACTIVE] = @@COLPREFIX@_darkest } +style "selection_clock_display" +{ + font_name = "monospace @FONT_SMALLER@" + + text[NORMAL] = @@COLPREFIX@_contrasting_indicator + text[ACTIVE] = @@COLPREFIX@_bright_indicator + fg[NORMAL] = @@COLPREFIX@_contrasting_indicator + fg[ACTIVE] = @@COLPREFIX@_bright_indicator + fg[SELECTED] = @@COLPREFIX@_bright_indicator + base[NORMAL] = @@COLPREFIX@_darkest + base[ACTIVE] = @@COLPREFIX@_darkest + bg[NORMAL] = @@COLPREFIX@_darkest + bg[ACTIVE] = @@COLPREFIX@_darkest +} + +style "punch_clock_display" = "very_small_text" +{ + font_name = "monospace @FONT_SMALLER@" + + text[NORMAL] = @@COLPREFIX@_contrasting_indicator + text[ACTIVE] = @@COLPREFIX@_bright_indicator + fg[NORMAL] = @@COLPREFIX@_contrasting_indicator + fg[ACTIVE] = @@COLPREFIX@_bright_indicator + fg[SELECTED] = @@COLPREFIX@_bright_indicator + base[NORMAL] = @@COLPREFIX@_darkest + base[ACTIVE] = @@COLPREFIX@_darkest + bg[NORMAL] = @@COLPREFIX@_darkest + bg[ACTIVE] = @@COLPREFIX@_darkest +} style "white_on_black_clock_display" = "medium_text" { @@ -1599,6 +1628,8 @@ widget "*InfoMessage" style:highest "info_message" widget "*WarningMessage" style:highest "warning_message" widget "*BigClockNonRecording" style:highest "non_recording_big_clock_display" widget "*BigClockRecording" style:highest "recording_big_clock_display" +widget "*SelectionClockDisplay" style:highest "selection_clock_display" +widget "*PunchClockDisplay" style:highest "punch_clock_display" widget "*TransportClockDisplay" style:highest "transport_clock_display" widget "*SecondaryClockDisplay" style:highest "transport_clock_display" widget "*TransportClockDisplayDelta" style:highest "transport_clock_display_delta" diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 6d96827971..0b22928c56 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -86,6 +86,7 @@ class ShuttleControl; class Splash; class SpeakerDialog; class ThemeManager; +class TimeInfoBox; class MidiTracer; class WindowProxyBase; class GlobalPortMatrixWindow; @@ -197,6 +198,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr AudioClock* preroll_clock; AudioClock* postroll_clock; + TimeInfoBox* time_info_box; + void store_clock_modes (); void restore_clock_modes (); void reset_main_clocks (); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 80ef975b91..70962befd6 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -32,6 +32,7 @@ #include "pbd/error.h" #include "pbd/basename.h" #include "pbd/fastlog.h" +#include #include #include #include @@ -54,6 +55,7 @@ #include "global_port_matrix.h" #include "location_ui.h" #include "rc_option_editor.h" +#include "time_info_box.h" #include "i18n.h" @@ -385,8 +387,13 @@ ARDOUR_UI::setup_transport () transport_hbox->pack_start (rec_button, false, false, 6); HBox* clock_box = manage (new HBox); + clock_box->set_border_width (2); + primary_clock->main_display().set_ypad (2); + primary_clock->set_border_width (2); clock_box->pack_start (*primary_clock, false, false); if (!ARDOUR::Profile->get_small_screen()) { + secondary_clock->set_border_width (2); + secondary_clock->main_display().set_ypad (2); clock_box->pack_start (*secondary_clock, false, false); } @@ -410,6 +417,9 @@ ARDOUR_UI::setup_transport () transport_tearoff_hbox.pack_start (*transport_vbox, false, false, 0); transport_tearoff_hbox.pack_start (*clock_box, false, false, 0); + time_info_box = manage (new TimeInfoBox); + transport_tearoff_hbox.pack_start (*time_info_box, false, false); + HBox* toggle_box = manage(new HBox); VBox* punch_box = manage (new VBox); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 903df41336..c5853c1fc3 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -44,6 +44,7 @@ #include "speaker_dialog.h" #include "sfdb_ui.h" #include "theme_manager.h" +#include "time_info_box.h" #include "i18n.h" @@ -97,6 +98,7 @@ ARDOUR_UI::set_session (Session *s) big_clock->set_session (s); preroll_clock->set_session (s); postroll_clock->set_session (s); + time_info_box->set_session (s); /* sensitize menu bar options that are now valid */ diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index fefff9e8d7..15b3131b4c 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -54,34 +54,19 @@ using PBD::atof; sigc::signal AudioClock::ModeChanged; vector AudioClock::clocks; -std::map AudioClock::field_length; - -void -AudioClock::fill_field_lengths() -{ - field_length[Timecode_Hours] = 2; - field_length[Timecode_Minutes] = 2; - field_length[Timecode_Seconds] = 2; - field_length[Timecode_Frames] = 2; - field_length[MS_Hours] = 2; - field_length[MS_Minutes] = 2; - field_length[MS_Seconds] = 2; - field_length[MS_Milliseconds] = 3; - field_length[Bars] = 4; - field_length[Beats] = 2; - field_length[Ticks] = 4; - field_length[AudioFrames] = 10; - - field_length[Timecode_LowerLeft1] = 4; - field_length[Timecode_LowerLeft2] = 4; - field_length[Timecode_LowerRight1] = 3; - field_length[Timecode_LowerRight2] = 6; // 29.97 D - - field_length[BBT_LowerLeft1] = 1; - field_length[BBT_LowerLeft2] = 7; - field_length[BBT_LowerRight1] = 1; - field_length[BBT_LowerRight2] = 3; - +uint32_t AudioClock::field_length[] = { + 2, /* Timecode_Hours */ + 2, /* Timecode_Minutes */ + 2, /* Timecode_Seconds */ + 2, /* Timecode_Frames */ + 2, /* MS_Hours */ + 2, /* MS_Minutes */ + 2, /* MS_Seconds */ + 3, /* MS_Milliseconds */ + 4, /* Bars */ + 2, /* Beats */ + 4, /* Ticks */ + 10, /* AudioFrames */ }; AudioClock::AudioClock (const string& clock_name, bool transient, const string& widget_name, @@ -91,22 +76,12 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string& , is_duration (duration) , editable (allow_edit) , _follows_playhead (follows_playhead) - , timecode_supplemental_left (0) - , timecode_supplemental_right (0) - , bbt_supplemental_left (0) - , bbt_supplemental_right (0) + , supplemental_left (0) + , supplemental_right (0) , last_when(0) , _canonical_time_is_displayed (true) , _canonical_time (0) { - CairoTextCell* tc; - CairoBarCell* bc; - CairoColonCell* cc; - - if (field_length.empty()) { - fill_field_lengths (); - } - last_when = 0; last_hrs = 9999; @@ -128,193 +103,71 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string& dragging = false; bbt_reference_time = -1; editing_field = (Field) 0; - current_cet = 0; - - frames_upper_info_label = 0; - frames_lower_info_label = 0; /* basic per-mode editable text "arrays" */ - timecode = new CairoEditableText (); - minsec = new CairoEditableText (); - bbt = new CairoEditableText (); - frames = new CairoEditableText (); - - // add an extra 0.6 "average char width" for the negative sign - tc = new CairoTextCell (field_length[Timecode_Hours] + 0.6); - _text_cells[Timecode_Hours] = tc; - timecode->add_cell (Timecode_Hours, tc); - - cc = new CairoColonCell (); - _fixed_cells[Timecode_Colon1] = cc; - timecode->add_cell (Timecode_Colon1, cc); + display = new CairoEditableText (); - tc = new CairoTextCell (field_length[Timecode_Minutes]); - _text_cells[Timecode_Minutes] = tc; - timecode->add_cell (Timecode_Minutes, tc); + _fixed_cells[Colon1] = new CairoColonCell (Colon1); + _fixed_cells[Colon2] = new CairoColonCell (Colon2); + _fixed_cells[Colon3] = new CairoColonCell (Colon3); + _fixed_cells[Bar1] = new CairoBarCell (Bar1); + _fixed_cells[Bar2] = new CairoBarCell (Bar2); - cc = new CairoColonCell (); - _fixed_cells[Timecode_Colon2] = cc; - timecode->add_cell (Timecode_Colon2, cc); - - tc = new CairoTextCell (field_length[Timecode_Seconds]); - _text_cells[Timecode_Seconds] = tc; - timecode->add_cell (Timecode_Seconds, tc); - - cc = new CairoColonCell (); - _fixed_cells[Timecode_Colon3] = cc; - timecode->add_cell (Timecode_Colon3, cc); - - tc = new CairoTextCell (field_length[Timecode_Frames]); - _text_cells[Timecode_Frames] = tc; - timecode->add_cell (Timecode_Frames, tc); + // add an extra 0.6 "average char width" for the negative sign + _text_cells[Timecode_Hours] = new CairoTextCell (Timecode_Hours, field_length[Timecode_Hours] + 0.6); + _text_cells[Timecode_Minutes] = new CairoTextCell (Timecode_Minutes, field_length[Timecode_Minutes]); + _text_cells[Timecode_Seconds] = new CairoTextCell (Timecode_Seconds, field_length[Timecode_Seconds]); + _text_cells[Timecode_Frames] = new CairoTextCell (Timecode_Frames, field_length[Timecode_Frames]); /* Minutes/Seconds */ - tc = new CairoTextCell (field_length[MS_Hours]); - _text_cells[MS_Hours] = tc; - minsec->add_cell (MS_Hours, tc); - - cc = new CairoColonCell (); - _fixed_cells[MS_Colon1] = cc; - minsec->add_cell (MS_Colon1, cc); - - tc = new CairoTextCell (field_length[MS_Minutes]); - _text_cells[MS_Minutes] = tc; - minsec->add_cell (MS_Minutes, tc); - - cc = new CairoColonCell (); - _fixed_cells[MS_Colon2] = cc; - minsec->add_cell (MS_Colon2, cc); - - tc = new CairoTextCell (field_length[MS_Seconds]); - _text_cells[MS_Seconds] = tc; - minsec->add_cell (MS_Seconds, tc); - - cc = new CairoColonCell (); - _fixed_cells[MS_Colon3] = cc; - minsec->add_cell (MS_Colon3, cc); - - tc = new CairoTextCell (field_length[MS_Milliseconds]); - _text_cells[MS_Milliseconds] = tc; - minsec->add_cell (MS_Milliseconds, tc); + _text_cells[MS_Hours] = new CairoTextCell (MS_Hours, field_length[MS_Hours]); + _text_cells[MS_Minutes] = new CairoTextCell (MS_Minutes, field_length[MS_Minutes]); + _text_cells[MS_Seconds] = new CairoTextCell (MS_Seconds, field_length[MS_Seconds]); + _text_cells[MS_Milliseconds] = new CairoTextCell (MS_Milliseconds, field_length[MS_Milliseconds]); /* Beats/Bars/Ticks */ - tc = new CairoTextCell (field_length[Bars]); - _text_cells[Bars] = tc; - bbt->add_cell (Bars, tc); - - bc = new CairoBarCell (); - _fixed_cells[BBT_Bar1] = bc; - bbt->add_cell (BBT_Bar1, bc); - - tc = new CairoTextCell (field_length[Beats]); - _text_cells[Beats] = tc; - bbt->add_cell (Beats, tc); - - bc = new CairoBarCell (); - _fixed_cells[BBT_Bar2] = bc; - bbt->add_cell (BBT_Bar2, bc); - - tc = new CairoTextCell (field_length[Ticks]); - _text_cells[Ticks] = tc; - bbt->add_cell (Ticks, tc); + _text_cells[Bars] = new CairoTextCell (Bars, field_length[Bars]); + _text_cells[Beats] = new CairoTextCell (Beats, field_length[Beats]); + _text_cells[Ticks] = new CairoTextCell (Ticks, field_length[Ticks]); /* Audio Frames */ - tc = new CairoTextCell (field_length[AudioFrames]); - _text_cells[AudioFrames] = tc; - frames->add_cell (AudioFrames, tc); - - frames_packer.set_homogeneous (false); - frames_packer.set_border_width (2); - frames_packer.pack_start (*frames); + _text_cells[AudioFrames] = new CairoTextCell (AudioFrames, field_length[AudioFrames]); - /* Timecode */ - - timecode_packer.set_homogeneous (false); - timecode_packer.set_border_width (2); + packer.set_homogeneous (false); if (with_info) { - timecode_supplemental_left = new CairoEditableText (); - tc = new CairoTextCell (field_length[Timecode_LowerLeft1]); - _text_cells[Timecode_LowerLeft1] = tc; - timecode_supplemental_left->add_cell (Timecode_LowerLeft1, tc); - tc = new CairoTextCell (field_length[Timecode_LowerLeft2]); - _text_cells[Timecode_LowerLeft2] = tc; - timecode_supplemental_left->add_cell (Timecode_LowerLeft2, tc); - - timecode_supplemental_right = new CairoEditableText (); - tc = new CairoTextCell (field_length[Timecode_LowerRight1]); - _text_cells[Timecode_LowerRight1] = tc; - timecode_supplemental_right->add_cell (Timecode_LowerRight1, tc); - tc = new CairoTextCell (field_length[Timecode_LowerRight2]); - _text_cells[Timecode_LowerRight2] = tc; - timecode_supplemental_right->add_cell (Timecode_LowerRight2, tc); - - timecode_supplemental_right->set_text (Timecode_LowerRight1, "FPS"); - /* LowerRight2 is set dynamically */ - - timecode_bottom.set_spacing (1); - timecode_bottom.set_homogeneous (false); - timecode_bottom.pack_start (*timecode_supplemental_left, true, true); - timecode_bottom.pack_start (*timecode_supplemental_right, true, true); - - timecode_top.pack_start (*timecode, true, true); - - timecode_packer.set_spacing (1); - timecode_packer.pack_start (timecode_top, true, true); - timecode_packer.pack_start (timecode_bottom, false, false); - } else { - timecode_packer.pack_start (*timecode, true, true); - } - /* BBT */ + supplemental_left = new CairoEditableText (); + supplemental_right = new CairoEditableText (); - bbt_packer.set_homogeneous (false); - bbt_packer.set_border_width (2); + /* field lengths of these cells will be set dynamically by ::set_mode() + */ - if (with_info) { - bbt_supplemental_left = new CairoEditableText (); - tc = new CairoTextCell (field_length[BBT_LowerLeft1]); - _text_cells[BBT_LowerLeft1] = tc; - bbt_supplemental_left->add_cell (BBT_LowerLeft1, tc); - tc = new CairoTextCell (field_length[BBT_LowerLeft2]); - _text_cells[BBT_LowerLeft2] = tc; - bbt_supplemental_left->add_cell (BBT_LowerLeft2, tc); - - bbt_supplemental_right = new CairoEditableText (); - tc = new CairoTextCell (field_length[BBT_LowerRight1]); - _text_cells[BBT_LowerRight1] = tc; - bbt_supplemental_right->add_cell (BBT_LowerRight1, tc); - tc = new CairoTextCell (field_length[BBT_LowerRight2]); - _text_cells[BBT_LowerRight2] = tc; - bbt_supplemental_right->add_cell (BBT_LowerRight2, tc); + _text_cells[LowerLeft1] = new CairoTextCell (LowerLeft1, 0); + _text_cells[LowerLeft2] = new CairoTextCell (LowerLeft2, 0); + _text_cells[LowerRight1] = new CairoTextCell (LowerRight1, 0); + _text_cells[LowerRight2] = new CairoTextCell (LowerRight2, 0); - bbt_supplemental_left->set_text (BBT_LowerLeft1, _("M")); // M is for meter - bbt_supplemental_right->set_text (BBT_LowerRight1, _("T")); // T is for tempo + bottom.set_spacing (1); + bottom.set_homogeneous (false); + bottom.pack_start (*supplemental_left, true, true); + bottom.pack_start (*supplemental_right, true, true); - /* LowerLeft2 and LowerRight2 are set dynamically */ - - bbt_bottom.set_spacing (1); - bbt_bottom.set_homogeneous (false); - bbt_bottom.pack_start (*bbt_supplemental_left, true, true); - bbt_bottom.pack_start (*bbt_supplemental_right, true, true); - - bbt_top.pack_start (*bbt, true, true); + top.pack_start (*display, true, true); - bbt_packer.set_spacing (1); - bbt_packer.pack_start (bbt_top, true, true); - bbt_packer.pack_start (bbt_bottom, false, false); - + packer.set_spacing (1); + packer.pack_start (top, true, true); + packer.pack_start (bottom, false, false); } else { - bbt_packer.pack_start (*bbt); + packer.pack_start (*display, true, true); } - - minsec_packer.set_homogeneous (false); - minsec_packer.set_border_width (2); - minsec_packer.pack_start (*minsec); + + add (packer); + show_all (); set_widget_name (widget_name); @@ -332,16 +185,21 @@ AudioClock::~AudioClock () /* these are not manage()'d, so that we can add/remove them from containers as necessary. */ - delete timecode; - delete minsec; - delete bbt; - delete frames; - delete timecode_supplemental_left; - delete timecode_supplemental_right; + delete display; + delete supplemental_left; + delete supplemental_right; + /* XXX need to delete all cells too */ } void -AudioClock::set_widget_name (string name) +AudioClock::set_font (const string& font) +{ + display->set_font (font); + /* XXX supplemental ... */ +} + +void +AudioClock::set_widget_name (const string& name) { Widget::set_name (name); @@ -366,18 +224,13 @@ AudioClock::set_theme () font = style->get_font(); } - timecode->set_font (font); - minsec->set_font (font); - bbt->set_font (font); - frames->set_font (font); + display->set_font (font); - if (timecode_supplemental_right) { + if (supplemental_right) { Pango::FontDescription smaller_font ("Sans 8"); - timecode_supplemental_right->set_font (smaller_font); - timecode_supplemental_left->set_font (smaller_font); - bbt_supplemental_right->set_font (smaller_font); - bbt_supplemental_left->set_font (smaller_font); + supplemental_right->set_font (smaller_font); + supplemental_left->set_font (smaller_font); } Gdk::Color bg = style->get_base (Gtk::STATE_NORMAL); @@ -389,16 +242,11 @@ AudioClock::set_theme () b = bg.get_blue_p (); a = 1.0; - timecode->set_bg (r, g, b, a); - minsec->set_bg (r, g, b, a); - bbt->set_bg (r, g, b, a); - frames->set_bg (r, g, b, a); + display->set_bg (r, g, b, a); - if (timecode_supplemental_right) { - timecode_supplemental_right->set_bg (r,g,b,a); - timecode_supplemental_left->set_bg (r,g,b,a); - bbt_supplemental_right->set_bg (r,g,b,a); - bbt_supplemental_left->set_bg (r,g,b,a); + if (supplemental_right) { + supplemental_right->set_bg (r,g,b,a); + supplemental_left->set_bg (r,g,b,a); } r = fg.get_red_p (); @@ -406,16 +254,11 @@ AudioClock::set_theme () b = fg.get_blue_p (); a = 1.0; - timecode->set_colors (r, g, b, a); - minsec->set_colors (r, g, b, a); - bbt->set_colors (r, g, b, a); - frames->set_colors (r, g, b, a); + display->set_colors (r, g, b, a); - if (timecode_supplemental_right) { - timecode_supplemental_right->set_colors (r,g,b,a); - timecode_supplemental_left->set_colors (r,g,b,a); - bbt_supplemental_right->set_colors (r,g,b,a); - bbt_supplemental_left->set_colors (r,g,b,a); + if (supplemental_right) { + supplemental_right->set_colors (r,g,b,a); + supplemental_left->set_colors (r,g,b,a); } r = eg.get_red_p (); @@ -423,16 +266,11 @@ AudioClock::set_theme () b = eg.get_blue_p (); a = 1.0; - timecode->set_edit_colors (r, g, b, a); - minsec->set_edit_colors (r, g, b, a); - bbt->set_edit_colors (r, g, b, a); - frames->set_edit_colors (r, g, b, a); + display->set_edit_colors (r, g, b, a); - if (timecode_supplemental_right) { - timecode_supplemental_right->set_edit_colors (r,g,b,a); - timecode_supplemental_left->set_edit_colors (r,g,b,a); - bbt_supplemental_right->set_edit_colors (r,g,b,a); - bbt_supplemental_left->set_edit_colors (r,g,b,a); + if (supplemental_right) { + supplemental_right->set_edit_colors (r,g,b,a); + supplemental_left->set_edit_colors (r,g,b,a); } queue_draw (); @@ -446,7 +284,7 @@ AudioClock::focus () void AudioClock::end_edit () { - current_cet->stop_editing (); + display->stop_editing (); editing_field = (Field) 0; key_entry_state = 0; @@ -563,32 +401,26 @@ AudioClock::set_frames (framepos_t when, bool /*force*/) char buf[32]; snprintf (buf, sizeof (buf), "%" PRId64, when); - frames->set_text (AudioFrames, buf); + display->set_text (_text_cells[AudioFrames], buf); - if (frames_upper_info_label) { + if (supplemental_left) { framecnt_t rate = _session->frame_rate(); if (fmod (rate, 1000.0) == 0.000) { sprintf (buf, "%" PRId64 "K", rate/1000); } else { - sprintf (buf, "%.3fK", rate/1000.0f); + sprintf (buf, "%" PRId64, rate); } - if (frames_upper_info_label->get_text() != buf) { - frames_upper_info_label->set_text (buf); - } + supplemental_left->set_text (_text_cells[LowerLeft2], buf); float vid_pullup = _session->config.get_video_pullup(); if (vid_pullup == 0.0) { - if (frames_lower_info_label->get_text () != _("none")) { - frames_lower_info_label->set_text(_("none")); - } + supplemental_right->set_text (_text_cells[LowerRight2], _("none")); } else { sprintf (buf, "%-6.4f", vid_pullup); - if (frames_lower_info_label->get_text() != buf) { - frames_lower_info_label->set_text (buf); - } + supplemental_right->set_text (_text_cells[LowerRight2], buf); } } } @@ -614,25 +446,25 @@ AudioClock::set_minsec (framepos_t when, bool force) if (force || hrs != ms_last_hrs) { sprintf (buf, "%02d", hrs); - minsec->set_text (MS_Hours, buf); + display->set_text (_text_cells[MS_Hours], buf); ms_last_hrs = hrs; } if (force || mins != ms_last_mins) { sprintf (buf, "%02d", mins); - minsec->set_text (MS_Minutes, buf); + display->set_text (_text_cells[MS_Minutes], buf); ms_last_mins = mins; } if (force || secs != ms_last_secs) { sprintf (buf, "%02d", secs); - minsec->set_text (MS_Seconds, buf); + display->set_text (_text_cells[MS_Seconds], buf); ms_last_secs = secs; } if (force || millisecs != ms_last_millisecs) { sprintf (buf, "%03d", millisecs); - minsec->set_text (MS_Milliseconds, buf); + display->set_text (_text_cells[MS_Milliseconds], buf); ms_last_millisecs = millisecs; } } @@ -655,30 +487,30 @@ AudioClock::set_timecode (framepos_t when, bool force) } else { sprintf (buf, " %0*" PRIu32, field_length[Timecode_Hours], TC.hours); } - timecode->set_text (Timecode_Hours, buf); + display->set_text (_text_cells[Timecode_Hours], buf); last_hrs = TC.hours; last_negative = TC.negative; } if (force || TC.minutes != last_mins) { sprintf (buf, "%0*" PRIu32, field_length[Timecode_Minutes], TC.minutes); - timecode->set_text (Timecode_Minutes, buf); + display->set_text (_text_cells[Timecode_Minutes], buf); last_mins = TC.minutes; } if (force || TC.seconds != last_secs) { sprintf (buf, "%0*" PRIu32, field_length[Timecode_Seconds], TC.seconds); - timecode->set_text (Timecode_Seconds, buf); + display->set_text (_text_cells[Timecode_Seconds], buf); last_secs = TC.seconds; } if (force || TC.frames != last_frames) { sprintf (buf, "%0*" PRIu32, field_length[Timecode_Frames], TC.frames); - timecode->set_text (Timecode_Frames, buf); + display->set_text (_text_cells[Timecode_Frames], buf); last_frames = TC.frames; } - if (timecode_supplemental_right) { + if (supplemental_right) { double timecode_frames = _session->timecode_frames_per_second(); bool drop; @@ -696,7 +528,7 @@ AudioClock::set_timecode (framepos_t when, bool force) sprintf (buf, "%.2f %s", timecode_frames, (drop ? "D" : "")); } - timecode_supplemental_right->set_text (Timecode_LowerRight2, buf); + supplemental_right->set_text (_text_cells[LowerRight2], buf); } } @@ -723,19 +555,18 @@ AudioClock::set_bbt (framepos_t when, bool force) sprintf (buf, "%0*" PRIu32, field_length[Bars], BBT.bars); if (force || _text_cells[Bars]->get_text () != buf) { - bbt->set_text (Bars, buf); - _text_cells[Bars]->set_text (buf); + display->set_text (_text_cells[Bars], buf); } sprintf (buf, "%0*" PRIu32, field_length[Beats], BBT.beats); if (force || _text_cells[Beats]->get_text () != buf) { - bbt->set_text (Beats, buf); + display->set_text (_text_cells[Beats], buf); } sprintf (buf, "%0*" PRIu32, field_length[Ticks], BBT.ticks); if (force || _text_cells[Ticks]->get_text () != buf) { - bbt->set_text (Ticks, buf); + display->set_text (_text_cells[Ticks], buf); } - if (bbt_supplemental_right) { + if (supplemental_right) { framepos_t pos; if (bbt_reference_time < 0) { @@ -747,10 +578,10 @@ AudioClock::set_bbt (framepos_t when, bool force) TempoMetric m (_session->tempo_map().metric_at (pos)); sprintf (buf, "%-5.2f", m.tempo().beats_per_minute()); - bbt_supplemental_left->set_text (BBT_LowerLeft2, buf); + supplemental_left->set_text (_text_cells[LowerLeft2], buf); sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor()); - bbt_supplemental_right->set_text (BBT_LowerRight2, buf); + supplemental_right->set_text (_text_cells[LowerRight2], buf); } } @@ -790,15 +621,15 @@ AudioClock::edit_next_field () case Timecode_Hours: editing_field = Timecode_Minutes; - timecode->start_editing (Timecode_Minutes); + display->start_editing (_text_cells[Timecode_Minutes]); break; case Timecode_Minutes: editing_field = Timecode_Seconds; - timecode->start_editing (Timecode_Seconds); + display->start_editing (_text_cells[Timecode_Seconds]); break; case Timecode_Seconds: editing_field = Timecode_Frames; - timecode->start_editing (Timecode_Frames); + display->start_editing (_text_cells[Timecode_Frames]); break; case Timecode_Frames: end_edit (); @@ -808,15 +639,15 @@ AudioClock::edit_next_field () case MS_Hours: editing_field = MS_Minutes; - minsec->start_editing (MS_Minutes); + display->start_editing (_text_cells[MS_Minutes]); break; case MS_Minutes: editing_field = MS_Seconds; - minsec->start_editing (MS_Seconds); + display->start_editing (_text_cells[MS_Seconds]); break; case MS_Seconds: editing_field = MS_Milliseconds; - minsec->start_editing (MS_Milliseconds); + display->start_editing (_text_cells[MS_Milliseconds]); break; case MS_Milliseconds: end_edit (); @@ -826,11 +657,11 @@ AudioClock::edit_next_field () case Bars: editing_field = Beats; - bbt->start_editing (Beats); + display->start_editing (_text_cells[Beats]); break; case Beats: editing_field = Ticks; - bbt->start_editing (Ticks); + display->start_editing (_text_cells[Ticks]); break; case Ticks: end_edit (); @@ -997,11 +828,7 @@ AudioClock::on_key_release_event (GdkEventKey *ev) } new_text += new_char; - - if (current_cet) { - current_cet->set_text (editing_field, new_text); - } - + display->set_text (cell, new_text); _canonical_time_is_displayed = true; key_entry_state++; } @@ -1033,13 +860,13 @@ AudioClock::on_key_release_event (GdkEventKey *ev) // Bars should never be zero, unless this clock is for a duration if (atoi (_text_cells[Bars]->get_text()) == 0 && !is_duration) { snprintf (buf, sizeof (buf), "%0*" PRIu32, field_length[Bars], 1); - _text_cells[Bars]->set_text (buf); + display->set_text (_text_cells[Bars], buf); _canonical_time_is_displayed = true; } // beats should never be zero, unless this clock is for a duration if (atoi (_text_cells[Beats]->get_text()) == 0 && !is_duration) { snprintf (buf, sizeof (buf), "%0*" PRIu32, field_length[Beats], 1); - _text_cells[Beats]->set_text (buf); + display->set_text (_text_cells[Beats], buf); _canonical_time_is_displayed = true; } break; @@ -1064,14 +891,14 @@ AudioClock::on_key_release_event (GdkEventKey *ev) } bool -AudioClock::button_press (GdkEventButton *ev, uint32_t id) +AudioClock::button_press (GdkEventButton *ev, CairoCell* cell) { - Field field = (Field) id; - switch (ev->button) { case 1: - editing_field = field; - current_cet->start_editing (field); + if (cell) { + editing_field = (Field) cell->id (); + display->start_editing (cell); + } Keyboard::magic_widget_grab_focus (); @@ -1094,7 +921,7 @@ AudioClock::button_press (GdkEventButton *ev, uint32_t id) } bool -AudioClock::button_release (GdkEventButton *ev, uint32_t id) +AudioClock::button_release (GdkEventButton *ev, CairoCell*) { if (dragging) { gdk_pointer_ungrab (GDK_CURRENT_TIME); @@ -1125,10 +952,8 @@ AudioClock::button_release (GdkEventButton *ev, uint32_t id) } bool -AudioClock::scroll (GdkEventScroll *ev, uint32_t id) +AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell) { - Field field = (Field) id; - if (_session == 0) { return false; } @@ -1138,38 +963,38 @@ AudioClock::scroll (GdkEventScroll *ev, uint32_t id) switch (ev->direction) { case GDK_SCROLL_UP: - frames = get_frames (field); - if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - frames *= 10; - } - set (current_time() + frames, true); - ValueChanged (); /* EMIT_SIGNAL */ - } - break; - + frames = get_frames ((Field) cell->id()); + if (frames != 0) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { + frames *= 10; + } + set (current_time() + frames, true); + ValueChanged (); /* EMIT_SIGNAL */ + } + break; + case GDK_SCROLL_DOWN: - frames = get_frames (field); - if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - frames *= 10; - } - - if ((double)current_time() - (double)frames < 0.0) { - set (0, true); - } else { - set (current_time() - frames, true); - } - - ValueChanged (); /* EMIT_SIGNAL */ - } - break; - + frames = get_frames ((Field) cell->id()); + if (frames != 0) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { + frames *= 10; + } + + if ((double)current_time() - (double)frames < 0.0) { + set (0, true); + } else { + set (current_time() - frames, true); + } + + ValueChanged (); /* EMIT_SIGNAL */ + } + break; + default: return false; break; } - + return true; } @@ -1355,31 +1180,31 @@ AudioClock::timecode_sanitize_display() { // Check Timecode fields for sanity, possibly adjusting values if (atoi (_text_cells[Timecode_Minutes]->get_text()) > 59) { - _text_cells[Timecode_Minutes]->set_text("59"); + display->set_text (_text_cells[Timecode_Minutes], "59"); _canonical_time_is_displayed = true; } if (atoi (_text_cells[Timecode_Seconds]->get_text()) > 59) { - _text_cells[Timecode_Seconds]->set_text("59"); + display->set_text (_text_cells[Timecode_Seconds], "59"); _canonical_time_is_displayed = true; } switch ((long)rint(_session->timecode_frames_per_second())) { case 24: if (atoi (_text_cells[Timecode_Frames]->get_text()) > 23) { - _text_cells[Timecode_Frames]->set_text("23"); + display->set_text (_text_cells[Timecode_Frames], "23"); _canonical_time_is_displayed = true; } break; case 25: if (atoi (_text_cells[Timecode_Frames]->get_text()) > 24) { - _text_cells[Timecode_Frames]->set_text("24"); + display->set_text (_text_cells[Timecode_Frames], "24"); _canonical_time_is_displayed = true; } break; case 30: if (atoi (_text_cells[Timecode_Frames]->get_text()) > 29) { - _text_cells[Timecode_Frames]->set_text("29"); + display->set_text (_text_cells[Timecode_Frames], "29"); _canonical_time_is_displayed = true; } break; @@ -1389,7 +1214,7 @@ AudioClock::timecode_sanitize_display() if (_session->timecode_drop_frames()) { if ((atoi (_text_cells[Timecode_Minutes]->get_text()) % 10) && (atoi (_text_cells[Timecode_Seconds]->get_text()) == 0) && (atoi (_text_cells[Timecode_Frames]->get_text()) < 2)) { - _text_cells[Timecode_Frames]->set_text("02"); + display->set_text (_text_cells[Timecode_Frames], "02"); _canonical_time_is_displayed = true; } } @@ -1924,67 +1749,124 @@ AudioClock::connect_signals () { disconnect_signals (); - if (editable && current_cet) { - scroll_connection = current_cet->scroll.connect (sigc::mem_fun (*this, &AudioClock::scroll)); - button_press_connection = current_cet->button_press.connect (sigc::mem_fun (*this, &AudioClock::button_press)); - button_release_connection = current_cet->button_release.connect (sigc::mem_fun (*this, &AudioClock::button_release)); + if (editable) { + scroll_connection = display->scroll.connect (sigc::mem_fun (*this, &AudioClock::scroll)); + button_press_connection = display->button_press.connect (sigc::mem_fun (*this, &AudioClock::button_press)); + button_release_connection = display->button_release.connect (sigc::mem_fun (*this, &AudioClock::button_release)); } } void AudioClock::set_mode (Mode m) { - /* slightly tricky: this is called from within the ARDOUR_UI - constructor by some of its clock members. at that time - the instance pointer is unset, so we have to be careful. - the main idea is to drop keyboard focus in case we had - started editing the clock and then we switch clock mode. - */ - - // clock_base.grab_focus (); - if (_mode == m) { return; } - remove (); _mode = m; + display->clear_cells (); + + if (supplemental_left) { + supplemental_left->clear_cells (); + supplemental_right->clear_cells (); + } + switch (_mode) { case Timecode: - current_cet = timecode; - add (timecode_packer); + display->add_cell (_text_cells[Timecode_Hours]); + display->add_cell (_fixed_cells[Colon1]); + display->add_cell (_text_cells[Timecode_Minutes]); + display->add_cell (_fixed_cells[Colon2]); + display->add_cell (_text_cells[Timecode_Seconds]); + display->add_cell (_fixed_cells[Colon3]); + display->add_cell (_text_cells[Timecode_Frames]); + + if (supplemental_left) { + supplemental_left->add_cell (_text_cells[LowerLeft1]); + supplemental_left->add_cell (_text_cells[LowerLeft2]); + supplemental_right->add_cell (_text_cells[LowerRight1]); + supplemental_right->add_cell (_text_cells[LowerRight2]); + + supplemental_left->set_width_chars (_text_cells[LowerLeft1], 4); + supplemental_left->set_width_chars (_text_cells[LowerLeft2], 8); + + supplemental_right->set_width_chars (_text_cells[LowerRight1], 4); + supplemental_right->set_width_chars (_text_cells[LowerRight2], 6.25); + + supplemental_left->set_text (_text_cells[LowerLeft1], _("EXT")); + supplemental_right->set_text (_text_cells[LowerRight1], _("FPS")); + } break; case BBT: - current_cet = bbt; - add (bbt_packer); + display->add_cell (_text_cells[Bars]); + display->add_cell (_fixed_cells[Bar1]); + display->add_cell (_text_cells[Beats]); + display->add_cell (_fixed_cells[Bar2]); + display->add_cell (_text_cells[Ticks]); + if (supplemental_left) { + supplemental_left->add_cell (_text_cells[LowerLeft1]); + supplemental_left->add_cell (_text_cells[LowerLeft2]); + supplemental_right->add_cell (_text_cells[LowerRight1]); + supplemental_right->add_cell (_text_cells[LowerRight2]); + + supplemental_left->set_width_chars (_text_cells[LowerLeft1], 1); + supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5.25); + + supplemental_right->set_width_chars (_text_cells[LowerRight1], 1); + supplemental_right->set_width_chars (_text_cells[LowerRight2], 5); + + supplemental_left->set_text (_text_cells[LowerLeft1], _("M")); + supplemental_right->set_text (_text_cells[LowerRight1], _("T")); + } break; case MinSec: - current_cet = minsec; - add (minsec_packer); + display->add_cell (_text_cells[MS_Hours]); + display->add_cell (_fixed_cells[Colon1]); + display->add_cell (_text_cells[MS_Minutes]); + display->add_cell (_fixed_cells[Colon2]); + display->add_cell (_text_cells[MS_Seconds]); + display->add_cell (_fixed_cells[Colon3]); + display->add_cell (_text_cells[MS_Milliseconds]); break; case Frames: - current_cet = frames; - add (frames_packer); + display->add_cell (_text_cells[AudioFrames]); + if (supplemental_left) { + supplemental_left->add_cell (_text_cells[LowerLeft1]); + supplemental_left->add_cell (_text_cells[LowerLeft2]); + supplemental_right->add_cell (_text_cells[LowerRight1]); + supplemental_right->add_cell (_text_cells[LowerRight2]); + + supplemental_left->set_width_chars (_text_cells[LowerLeft1], 3); + supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5); + + supplemental_right->set_width_chars (_text_cells[LowerRight1], 5); + supplemental_right->set_width_chars (_text_cells[LowerRight2], 5); + + supplemental_left->set_text (_text_cells[LowerLeft1], _("SR")); + supplemental_right->set_text (_text_cells[LowerRight1], _("Pull")); + } break; case Off: - current_cet = 0; - add (off_hbox); break; } - if (current_cet) { + if (supplemental_left) { + /* clear information cells */ + supplemental_left->set_text (_text_cells[LowerLeft2], _("")); + supplemental_right->set_text (_text_cells[LowerRight2], _("")); + } + + if (_mode != Off) { connect_signals (); } else { disconnect_signals (); } - get_child()->show_all (); - set (last_when, true); if (!is_transient) { @@ -2017,3 +1899,4 @@ AudioClock::set_is_duration (bool yn) is_duration = yn; set (last_when, true, 0, 's'); } + diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h index 1b1b24c503..df6def4f39 100644 --- a/gtk2_ardour/audio_clock.h +++ b/gtk2_ardour/audio_clock.h @@ -25,9 +25,7 @@ #include #include #include -#include #include -#include #include "ardour/ardour.h" #include "ardour/session_handle.h" @@ -66,7 +64,8 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr void set_bbt_reference (framepos_t); void set_is_duration (bool); - void set_widget_name (std::string); + void set_widget_name (const std::string&); + void set_font (const std::string&); std::string name() const { return _name; } @@ -83,6 +82,10 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr static bool has_focus() { return _has_focus; } + CairoEditableText& main_display () const { return *display; } + CairoEditableText* supplemental_left_display () const { return supplemental_left; } + CairoEditableText* supplemental_right_display () const { return supplemental_right; } + private: Mode _mode; uint32_t key_entry_state; @@ -95,46 +98,32 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr Gtk::Menu *ops_menu; - CairoEditableText* timecode; - CairoEditableText* minsec; - CairoEditableText* bbt; - CairoEditableText* frames; + CairoEditableText* display; enum Field { - /* Field IDs must start at 1. Cell ID zero - is reserved in CairoEditableText - */ - - Timecode_Hours = 1, - Timecode_Colon1, + Timecode_Hours, Timecode_Minutes, - Timecode_Colon2, Timecode_Seconds, - Timecode_Colon3, Timecode_Frames, MS_Hours, - MS_Colon1, MS_Minutes, - MS_Colon2, - MS_Colon3, // to become a dot cell MS_Seconds, MS_Milliseconds, Bars, - BBT_Bar1, Beats, - BBT_Bar2, Ticks, AudioFrames, - Timecode_LowerLeft1, - Timecode_LowerLeft2, - Timecode_LowerRight1, - Timecode_LowerRight2, + Colon1, + Colon2, + Colon3, + Bar1, + Bar2, - BBT_LowerLeft1, - BBT_LowerLeft2, - BBT_LowerRight1, - BBT_LowerRight2, + LowerLeft1, + LowerLeft2, + LowerRight1, + LowerRight2, }; /** CairoCells of various kinds for each of our non-text Fields */ @@ -145,25 +134,13 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr Gtk::HBox off_hbox; - CairoEditableText* timecode_supplemental_left; - CairoEditableText* timecode_supplemental_right; - CairoEditableText* bbt_supplemental_left; - CairoEditableText* bbt_supplemental_right; - - Gtk::VBox timecode_packer; - Gtk::HBox timecode_top; - Gtk::HBox timecode_bottom; - Gtk::HBox minsec_packer; - Gtk::HBox bbt_top; - Gtk::HBox bbt_bottom; - Gtk::VBox bbt_packer; - Gtk::HBox frames_packer; - - Gtk::Label* frames_upper_info_label; - Gtk::Label* frames_lower_info_label; - Gtk::VBox frames_info_box; - - CairoEditableText* current_cet; + CairoEditableText* supplemental_left; + CairoEditableText* supplemental_right; + + Gtk::VBox packer; + Gtk::HBox top; + Gtk::HBox bottom; + Field editing_field; framepos_t bbt_reference_time; framepos_t last_when; @@ -200,9 +177,9 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr /* proxied from CairoEditableText */ - bool scroll (GdkEventScroll *ev, uint32_t); - bool button_press (GdkEventButton *ev, uint32_t); - bool button_release (GdkEventButton *ev, uint32_t); + bool scroll (GdkEventScroll *ev, CairoCell*); + bool button_press (GdkEventButton *ev, CairoCell*); + bool button_release (GdkEventButton *ev, CairoCell*); sigc::connection scroll_connection; sigc::connection button_press_connection; sigc::connection button_release_connection; @@ -230,8 +207,7 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr void session_configuration_changed (std::string); - static std::map field_length; - static void fill_field_lengths(); + static uint32_t field_length[]; static bool _has_focus; void on_style_changed (const Glib::RefPtr&); diff --git a/gtk2_ardour/time_info_box.cc b/gtk2_ardour/time_info_box.cc new file mode 100644 index 0000000000..a343277b18 --- /dev/null +++ b/gtk2_ardour/time_info_box.cc @@ -0,0 +1,206 @@ +/* + Copyright (C) 2011 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "pbd/compose.h" + +#include "gtkmm2ext/cairocell.h" +#include "gtkmm2ext/gui_thread.h" +#include "gtkmm2ext/utils.h" + +#include "ardour/location.h" +#include "ardour/session.h" + +#include "time_info_box.h" +#include "audio_clock.h" +#include "editor.h" + +#include "i18n.h" + +using namespace Gtk; +using namespace ARDOUR; + +TimeInfoBox::TimeInfoBox () + : Table (4, 4) +{ + selection_start = new AudioClock ("selection-start", false, "SelectionClockDisplay", false, false, false, false); + selection_end = new AudioClock ("selection-end", false, "SelectionClockDisplay", false, false, false, false); + selection_length = new AudioClock ("selection-length", false, "SelectionClockDisplay", false, false, true, false); + + punch_start = new AudioClock ("punch-start", false, "PunchClockDisplay", false, false, false, false); + punch_end = new AudioClock ("punch-end", false, "PunchClockDisplay", false, false, false, false); + + CairoEditableText& ss (selection_start->main_display()); + ss.set_ypad (1); + ss.set_xpad (1); + ss.set_corner_radius (0); + ss.set_draw_background (false); + + CairoEditableText& se (selection_end->main_display()); + se.set_ypad (1); + se.set_xpad (1); + se.set_corner_radius (0); + se.set_draw_background (false); + + CairoEditableText& sl (selection_length->main_display()); + sl.set_ypad (1); + sl.set_xpad (2); + sl.set_corner_radius (0); + sl.set_draw_background (false); + + CairoEditableText& ps (punch_start->main_display()); + ps.set_ypad (1); + ps.set_xpad (2); + ps.set_corner_radius (0); + ps.set_draw_background (false); + + CairoEditableText& pe (punch_end->main_display()); + pe.set_ypad (1); + pe.set_xpad (2); + pe.set_corner_radius (0); + pe.set_draw_background (false); + + selection_title.set_markup (string_compose ("%1", _("Selection"))); + punch_title.set_markup (string_compose ("%1", _("Punch"))); + + set_homogeneous (false); + set_spacings (0); + + Gtk::Label* l; + + attach (selection_title, 0, 2, 0, 1); + l = manage (new Label); + l->set_markup (string_compose ("%1", _("Start"))); + attach (*l, 0, 1, 1, 2); + attach (*selection_start, 1, 2, 1, 2); + l = manage (new Label); + l->set_markup (string_compose ("%1", _("End"))); + attach (*l, 0, 1, 2, 3); + attach (*selection_end, 1, 2, 2, 3); + l = manage (new Label); + l->set_markup (string_compose ("%1", _("Length"))); + attach (*l, 0, 1, 3, 4); + attach (*selection_length, 1, 2, 3, 4); + + attach (punch_title, 2, 4, 0, 1); + l = manage (new Label); + l->set_markup (string_compose ("%1", _("Start"))); + attach (*l, 2, 3, 1, 2); + attach (*punch_start, 3, 4, 1, 2); + l = manage (new Label); + l->set_markup (string_compose ("%1", _("End"))); + attach (*l, 2, 3, 2, 3); + attach (*punch_end, 3, 4, 2, 3); + + show_all (); + + Editor::instance().get_selection().TimeChanged.connect (sigc::mem_fun (*this, &TimeInfoBox::selection_changed)); +} + +TimeInfoBox::~TimeInfoBox () +{ + delete selection_length; + delete selection_end; + delete selection_start; + + delete punch_start; + delete punch_end; +} + +void +TimeInfoBox::set_session (Session* s) +{ + SessionHandlePtr::set_session (s); + + selection_start->set_session (s); + selection_end->set_session (s); + selection_length->set_session (s); + + punch_start->set_session (s); + punch_end->set_session (s); + + if (s) { + Location* punch = s->locations()->auto_punch_location (); + + if (punch) { + watch_punch (punch); + } + + _session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, + boost::bind (&TimeInfoBox::punch_location_changed, this, _1), gui_context()); + } +} + +void +TimeInfoBox::selection_changed () +{ + selection_start->set (Editor::instance().get_selection().time.start()); + selection_end->set (Editor::instance().get_selection().time.end_frame()); + selection_length->set (Editor::instance().get_selection().time.length()); +} + +void +TimeInfoBox::punch_location_changed (Location* loc) +{ + if (loc) { + watch_punch (loc); + } +} + +void +TimeInfoBox::watch_punch (Location* punch) +{ + punch_connections.drop_connections (); + + punch->start_changed.connect (punch_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_changed, this, _1), gui_context()); + punch->end_changed.connect (punch_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_changed, this, _1), gui_context()); + + punch_changed (punch); +} + +void +TimeInfoBox::punch_changed (Location* loc) +{ + if (!loc) { + punch_start->set (99999999); + punch_end->set (999999999); + return; + } + + punch_start->set (loc->start()); + punch_end->set (loc->end()); +} + +bool +TimeInfoBox::on_expose_event (GdkEventExpose* ev) +{ + Table::on_expose_event (ev); + + { + Cairo::RefPtr context = get_window()->create_cairo_context(); + + context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height); + context->clip (); + + context->set_source_rgba (0.01, 0.02, 0.21, 1.0); + Gtkmm2ext::rounded_rectangle (context, 0, 0, get_allocation().get_width(), get_allocation().get_height(), 5); + context->fill (); + } + + return false; +} diff --git a/gtk2_ardour/time_info_box.h b/gtk2_ardour/time_info_box.h new file mode 100644 index 0000000000..a1da519aed --- /dev/null +++ b/gtk2_ardour/time_info_box.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2011 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __time_info_box_h__ +#define __time_info_box_h__ + +#include + +#include +#include + +#include "ardour/ardour.h" +#include "ardour/session_handle.h" + +class CairoEditableText; +class CairoCell; +class CairoTextCell; + +namespace ARDOUR { + class Session; + class Location; +} + +class AudioClock; + +class TimeInfoBox : public Gtk::Table, public ARDOUR::SessionHandlePtr +{ + public: + TimeInfoBox (); + ~TimeInfoBox (); + + void set_session (ARDOUR::Session*); + + protected: + bool on_expose_event (GdkEventExpose*); + + private: + AudioClock* selection_start; + AudioClock* selection_end; + AudioClock* selection_length; + + AudioClock* punch_start; + AudioClock* punch_end; + + Gtk::Label selection_title; + Gtk::Label punch_title; + + void punch_changed (ARDOUR::Location*); + void punch_location_changed (ARDOUR::Location*); + void watch_punch (ARDOUR::Location*); + PBD::ScopedConnectionList punch_connections; + + void selection_changed (); +}; + + +#endif /* __time_info_box_h__ */ diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index a7467377e3..a5962f6f7b 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -217,6 +217,7 @@ gtk2_ardour_sources = [ 'time_axis_view.cc', 'time_axis_view_item.cc', 'time_fx_dialog.cc', + 'time_info_box.cc', 'time_selection.cc', 'track_selection.cc', 'track_view_list.cc', -- cgit v1.2.3