diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-17 22:49:13 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-17 22:49:13 +0000 |
commit | b25fbc8a956528a7c648eb3960782aa31cc2a36e (patch) | |
tree | b45c8e70e71dfea92cffd51ff9465d965d6fb333 | |
parent | f07c92530c7305fc79de28e8762efcae63040729 (diff) |
all new implementation of audio clocks, with entirely new editing model. not entirely finished, but lookable, and usable
git-svn-id: svn://localhost/ardour2/branches/3.0@10662 d708f5d6-7413-0410-9779-e7cbd77b26cf
29 files changed, 966 insertions, 1230 deletions
diff --git a/gtk2_ardour/ardour2_ui_dark_sae.rc.in b/gtk2_ardour/ardour2_ui_dark_sae.rc.in index 1b0635a1b9..9cf5cbd46b 100644 --- a/gtk2_ardour/ardour2_ui_dark_sae.rc.in +++ b/gtk2_ardour/ardour2_ui_dark_sae.rc.in @@ -1159,11 +1159,6 @@ style "location_row_button" = "default_button" font_name = "%FONT_NORMAL%" } -style "location_rows_clock" = "default_clock_display" -{ - font_name = "%FONT_BIG%" -} - style "pan_slider" { font_name = "%FONT_NORMAL%" @@ -1341,15 +1336,6 @@ widget "*AudioClockSMPTEUpperInfo" style:highest "tempo_meter_clock_display" widget "*AudioClockSMPTELowerInfo" style:highest "tempo_meter_clock_display" widget "*AudioClockBBTUpperInfo" style:highest "tempo_meter_clock_display" widget "*AudioClockBBTLowerInfo" style:highest "tempo_meter_clock_display" -widget "*SelectionStartClock" style:highest "default_clock_display" -widget "*SelectionEndClock" style:highest "default_clock_display" -widget "*EditPointClock" style:highest "default_clock_display" -widget "*PreRollClock" style:highest "default_clock_display" -widget "*PostRollClock" style:highest "default_clock_display" -widget "*NudgeClock" style:highest "default_clock_display" -widget "*InsertTimeClock" style:highest "default_clock_display" -widget "*ZoomRangeClock" style:highest "default_clock_display" -widget "*SMPTEOffsetClock" style:highest "default_clock_display" widget "*TransportLabel" style:highest "small_bold_text" widget "*TakeLabel" style:highest "small_bold_text" widget "*LocationLabel" style:highest "small_bold_text" diff --git a/gtk2_ardour/ardour3_fonts.rc.in b/gtk2_ardour/ardour3_fonts.rc.in index 8fbf37c30a..994238a7fb 100644 --- a/gtk2_ardour/ardour3_fonts.rc.in +++ b/gtk2_ardour/ardour3_fonts.rc.in @@ -55,6 +55,11 @@ style "larger_text" font_name = "@FONT_LARGE@" } +style "massive_text" +{ + font_name = "@FONT_MASSIVE@" +} + style "larger_bold_text" { font_name = "bold @FONT_LARGE@" diff --git a/gtk2_ardour/ardour3_styles.rc.in b/gtk2_ardour/ardour3_styles.rc.in index cfc6f7c2b7..7ea58511d7 100644 --- a/gtk2_ardour/ardour3_styles.rc.in +++ b/gtk2_ardour/ardour3_styles.rc.in @@ -60,15 +60,6 @@ style "very_small_red_active_and_selected_button" = "very_small_button" bg[SELECTED] = @@COLPREFIX@_bright_indicator } -style "punch_button" = "very_small_red_active_and_selected_button" -{ - font_name = "@FONT_SMALLER@" - - fg[ACTIVE] = @@COLPREFIX@_darkest - bg[ACTIVE] = @@COLPREFIX@_bright_indicator - bg[SELECTED] = @@COLPREFIX@_bright_indicator -} - style "small_red_active_and_selected_button" = "small_button" { fg[ACTIVE] = @@COLPREFIX@_darkest @@ -648,99 +639,6 @@ style "small_red_on_black_entry" = "small_bold_text" bg[ACTIVE] = @@COLPREFIX@_base } -# -# Clocks: "text" is the clock digits; "base" is the bg -# - -style "non_recording_big_clock_display" = "medium_entry" -{ - font_name = "@FONT_MASSIVE@" - - text[NORMAL] = @@COLPREFIX@_control_text - text[ACTIVE] = @@COLPREFIX@_bright_indicator - text[SELECTED] = @@COLPREFIX@_bright_indicator - text[PRELIGHT] = @@COLPREFIX@_bright_indicator - text[INSENSITIVE] = @@COLPREFIX@_bright_indicator - - base[NORMAL] = @@COLPREFIX@_control_base - base[ACTIVE] = shade(0.5,@@COLPREFIX@_bright_indicator) -} - -style "recording_big_clock_display" = "non_recording_big_clock_display" -{ - text[NORMAL] = darker(@@COLPREFIX@_arm) -} - -style "transport_clock_display" -{ - font_name = "@FONT_BOLD_BIG@" - - text[NORMAL] = darker (@@COLPREFIX@_contrasting_indicator) - text[ACTIVE] = darker (@@COLPREFIX@_bright_indicator) - text[SELECTED] = darker(@@COLPREFIX@_bright_indicator) - text[PRELIGHT] = darker(@@COLPREFIX@_bright_indicator) - text[INSENSITIVE] = darker(@@COLPREFIX@_bright_indicator) - - base[NORMAL] = @@COLPREFIX@_darkest - base[ACTIVE] = @@COLPREFIX@_darkest - bg[NORMAL] = @@COLPREFIX@_darkest - bg[ACTIVE] = @@COLPREFIX@_darkest -} - -style "transport_clock_display_delta" = "transport_clock_display" -{ - text[NORMAL] = @@COLPREFIX@_bright_color -} - -style "tempo_meter_clock_display" = "very_small_text" -{ - text[NORMAL] = @@COLPREFIX@_fg - text[ACTIVE] = @@COLPREFIX@_somewhat_bright_indicator - text[SELECTED] = @@COLPREFIX@_bright_indicator - base[NORMAL] = @@COLPREFIX@_base - base[ACTIVE] = @@COLPREFIX@_contrasting_indicator -} - -style "default_clock_display" = "medium_text" -{ - text[NORMAL] = @@COLPREFIX@_contrasting_indicator - text[ACTIVE] = @@COLPREFIX@_bright_indicator - text[SELECTED] = @@COLPREFIX@_bright_indicator - base[NORMAL] = @@COLPREFIX@_darkest - base[ACTIVE] = @@COLPREFIX@_darkest -} - -style "selection_clock_display" -{ - font_name = "@FONT_SMALLER@" - - text[NORMAL] = @@COLPREFIX@_contrasting_indicator - text[ACTIVE] = @@COLPREFIX@_bright_indicator - text[SELECTED] = @@COLPREFIX@_bright_indicator - base[NORMAL] = @@COLPREFIX@_darkest - base[ACTIVE] = @@COLPREFIX@_darkest -} - -style "punch_clock_display" = "very_small_text" -{ - font_name = "@FONT_SMALLER@" - - text[NORMAL] = @@COLPREFIX@_contrasting_indicator - text[ACTIVE] = @@COLPREFIX@_bright_indicator - text[SELECTED] = @@COLPREFIX@_bright_indicator - base[NORMAL] = @@COLPREFIX@_darkest - base[ACTIVE] = @@COLPREFIX@_darkest -} - -style "white_on_black_clock_display" = "medium_text" -{ - text[NORMAL] = @@COLPREFIX@_fg - text[ACTIVE] = @@COLPREFIX@_bright_indicator - base[SELECTED] = @@COLPREFIX@_bright_indicator - base[NORMAL] = @@COLPREFIX@_darkest - base[ACTIVE] = @@COLPREFIX@_darkest -} - style "editor_time_ruler" = "small_text" { fg[NORMAL] = @@COLPREFIX@_fg @@ -1019,10 +917,6 @@ style "location_row_button" = "default_button" font_name = "@FONT_NORMAL@" } -style "location_rows_clock" = "default_clock_display" -{ - font_name = "@FONT_NORMAL@" -} style "ardour_button" ="default_button" { diff --git a/gtk2_ardour/ardour3_ui_default.conf b/gtk2_ardour/ardour3_ui_default.conf index e5ffb95e23..40007c8680 100644 --- a/gtk2_ardour/ardour3_ui_default.conf +++ b/gtk2_ardour/ardour3_ui_default.conf @@ -639,5 +639,36 @@ <Option name="route button: text" value="c7c7d8ff"/> <Option name="route button: text active" value="c8c8d9ff"/> <Option name="route button: text mid" value="000000ff"/> + <Option name="transport clock: text" value="6bb620ff"/> + <Option name="transport clock: background" value="000000ff"/> + <Option name="transport clock: edited text" value="ff0000ff"/> + <Option name="secondary clock: text" value="6bb620ff"/> + <Option name="secondary clock: background" value="000000ff"/> + <Option name="secondary clock: edited text" value="ff0000ff"/> + <Option name="big clock: text" value="f0f0f0ff"/> + <Option name="big clock: background" value="020202ff"/> + <Option name="big clock: edited text" value="0073a3ff"/> + <Option name="big clock active: text" value="020202ff"/> + <Option name="big clock active: background" value="f11000ff"/> + <Option name="big clock active: edited text" value="0073a3ff"/> + <Option name="transport delta clock: text" value="0009f3ff"/> + <Option name="transport delta clock: background" value="000000ff"/> + <Option name="transport delta clock: edited text" value="ff0000ff"/> + <Option name="secondary delta clock: text" value="0009f3ff"/> + <Option name="secondary delta clock: background" value="000000ff"/> + <Option name="secondary delta clock: edited text" value="ff0000ff"/> + <Option name="punch clock: text" value="6bb620ff"/> + <Option name="punch clock: background" value="000000ff"/> + <Option name="punch clock: edited text" value="ff0000ff"/> + <Option name="nudge clock: text" value="6bb620ff"/> + <Option name="nudge clock: background" value="000000ff"/> + <Option name="nudge clock: edited text" value="ff0000ff"/> + <Option name="selection clock: text" value="6bb620ff"/> + <Option name="selection clock: background" value="000000ff"/> + <Option name="selection clock: edited text" value="ff0000ff"/> + <Option name="clock: text" value="6bb620ff"/> + <Option name="clock: background" value="000000ff"/> + <Option name="clock: edited text" value="ff0000ff"/> + </Canvas> </Ardour> diff --git a/gtk2_ardour/ardour3_widget_list.rc b/gtk2_ardour/ardour3_widget_list.rc index 2c04bc97f0..2c74737dd5 100644 --- a/gtk2_ardour/ardour3_widget_list.rc +++ b/gtk2_ardour/ardour3_widget_list.rc @@ -125,24 +125,21 @@ widget "*ErrorMessage" style:highest "error_message" widget "*FatalMessage" style:highest "fatal_message" 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" -widget "*SecondaryClockDisplayDelta" style:highest "transport_clock_display_delta" -widget "*SelectionStartClock" style:highest "default_clock_display" -widget "*SelectionEndClock" style:highest "default_clock_display" -widget "*SilenceDurationClock" style:highest "white_on_black_clock_display" -widget "*EditPointClock" style:highest "default_clock_display" -widget "*PreRollClock" style:highest "default_clock_display" -widget "*PostRollClock" style:highest "default_clock_display" -widget "*NudgeClock" style:highest "default_clock_display" -widget "*MenuBarClock" style:highest "default_clock_display" -widget "*ZoomRangeClock" style:highest "default_clock_display" -widget "*TimecodeOffsetClock" style:highest "default_clock_display" + +widget "*big clock" style:highest "massive_text" +widget "*selection clock" style:highest "small_text" +widget "*punch clock" style:highest "small_text" +widget "*transport clock" style:highest "large_bold_text" +widget "*secondary clock" style:highest "large_bold_text" +widget "*transport delta clock" style:highest "large_bold_text" +widget "*secondary delta clock" style:highest "large_bold_text" +widget "*silence duration clock" style:highest "medium_text" +widget "*edit point clock" style:highest "medium_text" +widget "*nudge clock" style:highest "medium_text" +widget "*menubar clock" style:highest "medium_text" +widget "*zoomrange clock" style:highest "medium_text" +widget "*timecodeoffset clock" style:highest "medium_text" + widget "*TransportLabel" style:highest "small_bold_text" widget "*TakeLabel" style:highest "small_bold_text" widget "*LocationLabel" style:highest "small_bold_text" @@ -250,7 +247,6 @@ widget "*MixerGroupList" style:highest "treeview_display" widget "*RegionEditorLabel" style:highest "medium_text" widget "*RegionEditorSmallLabel" style:highest "small_text" widget "*RegionEditorEntry" style:highest "medium_entry" -widget "*RegionEditorClock" style:highest "default_clock_display" widget "*RegionEditorToggleButton" style:highest "paler_bright_when_active" widget "*RegionEditorToggleButton*" style:highest "paler_bright_when_active" widget "*MixerStripSpeedBase" style:highest "small_entry" @@ -330,7 +326,7 @@ widget "*NewSessionChannelChoice" style:highest "medium_bold_entry" widget "*NewSessionMainButton" style:highest "large_bold_text" widget "*NewSessionMainButton*" style:highest "large_bold_text" widget "*NewSessionMainLabel" style:highest "large_bold_text" -widget "*LocationEditRowClock" style:highest "location_rows_clock" +widget "*location edit row clock" style:highest "medium_text" widget "*LocationEditNameLabel" style:highest "medium_text" widget "*LocationEditSetButton" style:highest "location_row_button" widget "*LocationEditSetButton*" style:highest "location_row_button" @@ -365,15 +361,13 @@ widget "*solo safe" style:highest "solo_safe" widget "*ContrastingPopup" style:highest "contrasting_popup" widget "*ContrastingPopup*" style:highest "contrasting_popup" widget "*MidiChannelSelectorButton" style:highest "midi_channel_selector_button" -widget "*TimeInfoSelectionTitle" style:highest "very_small_bright_when_active" -widget "*TimeInfoSelectionLabel" style:highest "very_small_bright_when_active" -widget "*TimeInfoPunchTitle" style:highest "very_small_bright_when_active" -widget "*TimeInfoPunchLabel" style:highest "very_small_bright_when_active" -widget "*TimeInfoPunchButton" style:highest "punch_button" +widget "*TimeInfoSelectionTitle" style:highest "very_small_text" +widget "*TimeInfoSelectionLabel" style:highest "very_small_text" +widget "*TimeInfoPunchTitle" style:highest "very_small_text" +widget "*TimeInfoPunchButton" style:highest "very_small_text" widget "*RouteNameEditorEntry" style:highest "text_cell_entry" widget "*RegionNameEditorEntry" style:highest "text_cell_entry" widget "*MixerMidiInputEnableButton" style:highest "mouse_mode_button" -widget "*InsertTimeClock" style:highest "default_clock_display" widget "*EditorRouteGroupsAllGroupButton" style:highest "default_toggle_button" widget "*MidiSoundNotesButton" style:highest "default_toggle_button" widget "*MeasureLatencyButton" style:highest "default_toggle_button" diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc index 68cfc22d79..3f9c31b4a5 100644 --- a/gtk2_ardour/ardour_button.cc +++ b/gtk2_ardour/ardour_button.cc @@ -628,20 +628,6 @@ ArdourButton::set_image (const RefPtr<Gdk::Pixbuf>& img) } void -ArdourButton::set_active (bool yn) -{ - /* this is an API simplification for buttons - that only use the Active and Normal states. - */ - - if (yn) { - set_active_state (Gtkmm2ext::Active); - } else { - unset_active_state (); - } -} - -void ArdourButton::set_active_state (Gtkmm2ext::ActiveState s) { bool changed = (_active_state != s); diff --git a/gtk2_ardour/ardour_button.h b/gtk2_ardour/ardour_button.h index 8da31a1066..fb0f8320a1 100644 --- a/gtk2_ardour/ardour_button.h +++ b/gtk2_ardour/ardour_button.h @@ -59,12 +59,6 @@ class ArdourButton : public CairoWidget void set_active_state (Gtkmm2ext::ActiveState); void set_visual_state (Gtkmm2ext::VisualState); - /* this is an API simplification for buttons - that only use the Active and Normal active states. - */ - void set_active (bool); - bool get_active () { return active_state() != Gtkmm2ext::ActiveState (0); } - void set_elements (Element); Element elements() const { return _elements; } diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 749e70e2ac..72b39ce8ba 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -137,12 +137,12 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp) , gui_object_state (new GUIObjectState) - , primary_clock (new AudioClock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true)) - , secondary_clock (new AudioClock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true)) + , primary_clock (new AudioClock (X_("primary"), false, X_("transport"), true, true, false, true)) + , secondary_clock (new AudioClock (X_("secondary"), false, X_("secondary"), true, true, false, true)) /* big clock */ - , big_clock (new AudioClock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, false)) + , big_clock (new AudioClock (X_("bigclock"), false, "big", true, true, false, false)) /* transport */ @@ -3638,13 +3638,10 @@ ARDOUR_UI::record_state_changed () return; } - Session::RecordState const r = _session->record_status (); - bool const h = _session->have_rec_enabled_track (); - - if (r == Session::Recording && h) { - big_clock->set_widget_name ("BigClockRecording"); + if (_session->record_status () == Session::Recording && _session->have_rec_enabled_track ()) { + big_clock->set_active (true); } else { - big_clock->set_widget_name ("BigClockNonRecording"); + big_clock->set_active (false); } } diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 23dac7e01b..f353c1c39d 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -371,6 +371,7 @@ ARDOUR_UI::setup_transport () tbox->pack_start (rec_button, false, false, 6); HBox* clock_box = manage (new HBox); + primary_clock->set_border_width (2); clock_box->pack_start (*primary_clock, false, false); if (!ARDOUR::Profile->get_small_screen()) { @@ -378,7 +379,6 @@ ARDOUR_UI::setup_transport () clock_box->pack_start (*secondary_clock, false, false); } - shuttle_box = new ShuttleControl; shuttle_box->show (); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index d5ff1b3c5c..328328040f 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -637,6 +637,7 @@ ARDOUR_UI::setup_clock () big_clock_window->set (new Window (WINDOW_TOPLEVEL), false); + big_clock_window->get()->set_resizable (true); big_clock_window->get()->set_keep_above (true); big_clock_window->get()->set_border_width (0); big_clock_window->get()->add (*big_clock); @@ -684,7 +685,7 @@ ARDOUR_UI::float_big_clock (Gtk::Window* parent) } void -ARDOUR_UI::big_clock_size_allocate (Gtk::Allocation&) +ARDOUR_UI::big_clock_size_allocate (Gtk::Allocation& alloc) { if (!big_clock_resize_in_progress) { Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::idle_big_clock_text_resizer), 0, 0)); diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 4c0c551c18..f2347d749c 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -26,7 +26,8 @@ #include <gtkmm/style.h> #include "gtkmm2ext/cairocell.h" -#include <gtkmm2ext/utils.h> +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/rgb_macros.h" #include "ardour/ardour.h" #include "ardour/session.h" @@ -48,27 +49,10 @@ using namespace std; using Gtkmm2ext::Keyboard; -using PBD::atoi; -using PBD::atof; - sigc::signal<void> AudioClock::ModeChanged; vector<AudioClock*> AudioClock::clocks; - -uint32_t AudioClock::field_length[] = { - 1, /* Timecode_Sign */ - 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 */ -}; +const double AudioClock::info_font_scale_factor = 0.6; +const double AudioClock::separator_height = 2.0; AudioClock::AudioClock (const string& clock_name, bool transient, const string& widget_name, bool allow_edit, bool follows_playhead, bool duration, bool with_info) @@ -78,248 +62,399 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string& , editable (allow_edit) , _follows_playhead (follows_playhead) , _off (false) - , supplemental_left (0) - , supplemental_right (0) + , _need_bg (true) + , ops_menu (0) + , editing_attr (0) + , background_attr (0) + , foreground_attr (0) + , mode_based_info_ratio (1.0) + , editing (false) + , bbt_reference_time (-1) , last_when(0) + , last_pdelta (0) + , last_sdelta (0) + , dragging (false) + , drag_field (Field (0)) , _canonical_time_is_displayed (true) , _canonical_time (0) -{ - last_when = 0; - - last_hrs = 9999; - last_mins = 9999; - last_secs = 9999; - last_frames = 99999; - ms_last_hrs = 9999; - ms_last_mins = 9999; - ms_last_secs = 9999; - ms_last_millisecs = 99999; +{ + set_flags (CAN_FOCUS); - last_negative = false; - - last_pdelta = 0; - last_sdelta = 0; - key_entry_state = 0; - ops_menu = 0; - dragging = false; - bbt_reference_time = -1; - editing_field = (Field) 0; - - /* basic per-mode editable text "arrays" */ - - display = new CairoEditableText (); - display->set_corner_radius (0); - - _fixed_cells[Colon1] = new CairoCharCell (Colon1, ':'); - _fixed_cells[Colon2] = new CairoCharCell (Colon2, ':'); - _fixed_cells[Colon3] = new CairoCharCell (Colon3, ':'); - _fixed_cells[Bar1] = new CairoCharCell (Bar1, '|'); - _fixed_cells[Bar2] = new CairoCharCell (Bar2, '|'); - - _text_cells[Timecode_Sign] = new CairoTextCell (Timecode_Sign, field_length[Timecode_Sign]); - _text_cells[Timecode_Hours] = new CairoTextCell (Timecode_Hours, field_length[Timecode_Hours]); - _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]); + _layout = Pango::Layout::create (get_pango_context()); + _layout->set_attributes (normal_attributes); - /* Minutes/Seconds */ - - _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]); + if (with_info) { + _left_layout = Pango::Layout::create (get_pango_context()); + _right_layout = Pango::Layout::create (get_pango_context()); + } - /* Beats/Bars/Ticks */ - - _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]); + set_widget_name (widget_name); - /* Audio Frames */ - - _text_cells[AudioFrames] = new CairoTextCell (AudioFrames, field_length[AudioFrames]); + _mode = BBT; /* lie to force mode switch */ + set_mode (Timecode); + set (last_when, true); - set_homogeneous (false); + if (!is_transient) { + clocks.push_back (this); + } +} - if (with_info) { +AudioClock::~AudioClock () +{ + delete background_attr; + delete foreground_attr; + delete editing_attr; +} - supplemental_left = new CairoEditableText (); - supplemental_right = new CairoEditableText (); +void +AudioClock::set_widget_name (const string& str) +{ + if (str.empty()) { + set_name ("clock"); + } else { + set_name (str + " clock"); + } +} - supplemental_left->set_corner_radius (0); - supplemental_right->set_corner_radius (0); - /* field lengths of these cells will be set dynamically by ::set_mode() - */ +void +AudioClock::on_realize () +{ + CairoWidget::on_realize (); + set_font (); + set_colors (); +} - _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); - - bottom.set_spacing (1); - bottom.set_homogeneous (false); - bottom.pack_start (*supplemental_left, true, true); - bottom.pack_start (*supplemental_right, true, true); +void +AudioClock::set_font () +{ + Glib::RefPtr<Gtk::Style> style = get_style (); + Pango::FontDescription font; + Pango::AttrFontDesc* font_attr; - top.pack_start (*display, true, true); - - set_spacing (1); - - pack_start (top, true, true); - pack_start (bottom, true, true); + if (!is_realized()) { + font = get_font_for_style (get_name()); } else { - pack_start (*display, true, true); + font = style->get_font(); } - show_all (); + font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); - set_widget_name (widget_name); + normal_attributes.change (*font_attr); + editing_attributes.change (*font_attr); - _mode = BBT; /* lie to force mode switch */ - set_mode (Timecode); - set (last_when, true); + /* now a smaller version of the same font */ - connect_signals (); + delete font_attr; + font.set_size ((int) lrint (font.get_size() * info_font_scale_factor)); + font.set_weight (Pango::WEIGHT_NORMAL); + font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); + + info_attributes.change (*font_attr); + + delete font_attr; +} - if (!is_transient) { - clocks.push_back (this); - } +void +AudioClock::set_active_state (Gtkmm2ext::ActiveState s) +{ + CairoWidget::set_active_state (s); + set_colors (); } - -AudioClock::~AudioClock () + +void +AudioClock::set_colors () { - /* these are not manage()'d, so that we can add/remove - them from containers as necessary. - */ + int r, g, b, a; - delete display; - delete supplemental_left; - delete supplemental_right; + uint32_t bg_color; + uint32_t text_color; + uint32_t editing_color; + + if (active_state()) { + bg_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 active: background", get_name())); + text_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 active: text", get_name())); + editing_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 active: edited text", get_name())); + } else { + bg_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: background", get_name())); + text_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: text", get_name())); + editing_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: edited text", get_name())); + } + + UINT_TO_RGBA (bg_color, &r, &g, &b, &a); + r = lrint ((r/256.0) * 65535.0); + g = lrint ((g/256.0) * 65535.0); + b = lrint ((b/256.0) * 65535.0); + background_attr = new Pango::AttrColor (Pango::Attribute::create_attr_background (r, g, b)); + + /* store for bg in ::render() */ + bg_r = r/256.0; + bg_g = g/256.0; + bg_b = b/256.0; + bg_a = a/256.0; + + UINT_TO_RGBA (text_color, &r, &g, &b, &a); + r = lrint ((r/256.0) * 65535.0); + g = lrint ((g/256.0) * 65535.0); + b = lrint ((b/256.0) * 65535.0); + foreground_attr = new Pango::AttrColor (Pango::Attribute::create_attr_foreground (r, g, b)); + + UINT_TO_RGBA (editing_color, &r, &g, &b, &a); + r = lrint ((r/256.0) * 65535.0); + g = lrint ((g/256.0) * 65535.0); + b = lrint ((b/256.0) * 65535.0); + editing_attr = new Pango::AttrColor (Pango::Attribute::create_attr_foreground (r, g, b)); + + normal_attributes.change (*background_attr); + normal_attributes.change (*foreground_attr); - for (std::map<Field,CairoCell*>::iterator i = _fixed_cells.begin(); i != _fixed_cells.end(); ++i) { - delete i->second; + info_attributes.change (*background_attr); + info_attributes.change (*foreground_attr); + + editing_attributes.change (*background_attr); + editing_attributes.change (*foreground_attr); + editing_attributes.change (*editing_attr); + + if (!editing) { + _layout->set_attributes (normal_attributes); + } else { + _layout->set_attributes (editing_attributes); } - for (std::map<Field,CairoTextCell*>::iterator i = _text_cells.begin(); i != _text_cells.end(); ++i) { - delete i->second; + if (_left_layout) { + _left_layout->set_attributes (info_attributes); + _right_layout->set_attributes (info_attributes); } + + queue_draw (); } void -AudioClock::set_widget_name (const string& name) +AudioClock::render (cairo_t* cr) { - Widget::set_name (name); + if (_need_bg) { + /* paint entire area the color of the parent window bg + + XXX try to optimize this so that we just paint the corners and + other areas that may be exposed by rounded corners. + */ + + Gdk::Color bg (get_parent_bg()); + cairo_rectangle (cr, 0, 0, _width, _height); + cairo_stroke_preserve (cr); + cairo_set_source_rgb (cr, bg.get_red_p(), bg.get_green_p(), bg.get_blue_p()); + cairo_fill (cr); + } + + /* main layout: rounded rect, plus the text */ + + cairo_set_source_rgba (cr, bg_r, bg_g, bg_b, bg_a); + Gtkmm2ext::rounded_rectangle (cr, 0, 0, _width, upper_height, 9); + + cairo_move_to (cr, 6, (upper_height - layout_height) / 2.0); + pango_cairo_show_layout (cr, _layout->gobj()); + + if (_left_layout) { + + double h = _height - upper_height - separator_height; - set_theme (); + if (mode_based_info_ratio != 1.0) { + + double left_rect_width = round (((_width - separator_height) * mode_based_info_ratio) + 0.5); + + cairo_set_source_rgba (cr, bg_r, bg_g, bg_b, bg_a); + Gtkmm2ext::rounded_rectangle (cr, 0, upper_height + separator_height, left_rect_width, h, 9); + + cairo_move_to (cr, 6, upper_height + separator_height + ((h - info_height)/2.0)); + pango_cairo_show_layout (cr, _left_layout->gobj()); + + Gtkmm2ext::rounded_rectangle (cr, left_rect_width + separator_height, upper_height + separator_height, + _width - separator_height - left_rect_width, h, 9); + + cairo_move_to (cr, 6 + left_rect_width + separator_height, upper_height + separator_height + ((h - info_height)/2.0)); + pango_cairo_show_layout (cr, _right_layout->gobj()); + + } else { + /* no info to display, or just one */ + + cairo_set_source_rgba (cr, bg_r, bg_g, bg_b, bg_a); + Gtkmm2ext::rounded_rectangle (cr, 0, upper_height + separator_height, _width, h, 9); + } + } } void -AudioClock::set_theme () +AudioClock::on_size_allocate (Gtk::Allocation& alloc) { - Glib::RefPtr<Gtk::Style> style = get_style (); - double r, g, b, a; - - if (!style) { - return; + CairoWidget::on_size_allocate (alloc); + + if (_left_layout) { + upper_height = (_height/2.0) - 1.0; + } else { + upper_height = _height; } +} +void +AudioClock::on_size_request (Gtk::Requisition* req) +{ + Glib::RefPtr<Pango::Layout> tmp; + Glib::RefPtr<Gtk::Style> style = get_style (); Pango::FontDescription font; + tmp = Pango::Layout::create (get_pango_context()); + if (!is_realized()) { font = get_font_for_style (get_name()); } else { font = style->get_font(); } - display->set_font (font); - + tmp->set_font_description (font); - if (supplemental_left) { - /* propagate font style, sort of, into supplemental text */ - boost::shared_ptr<CairoFontDescription> smaller_font (new CairoFontDescription (*display->font().get())); - smaller_font->set_size (12); - smaller_font->set_weight (Cairo::FONT_WEIGHT_NORMAL); - supplemental_right->set_font (smaller_font); - supplemental_left->set_font (smaller_font); - } - - Gdk::Color bg = style->get_base (Gtk::STATE_NORMAL); - Gdk::Color fg = style->get_text (Gtk::STATE_NORMAL); - Gdk::Color eg = style->get_text (Gtk::STATE_ACTIVE); + /* this string is the longest thing we will ever display, + and also includes the BBT "|" that may descends below + the baseline a bit, and a comma for the minsecs mode + where we printf a fractional value (XXX or should) + */ - r = bg.get_red_p (); - g = bg.get_green_p (); - b = bg.get_blue_p (); - a = 1.0; + tmp->set_text (" 88|88:88:88,88"); - display->set_bg (r, g, b, a); + tmp->get_pixel_size (req->width, req->height); - if (supplemental_right) { - supplemental_right->set_bg (r,g,b,a); - supplemental_left->set_bg (r,g,b,a); - } + layout_height = req->height; + layout_width = req->width; - r = fg.get_red_p (); - g = fg.get_green_p (); - b = fg.get_blue_p (); - a = 1.0; + /* now tackle height, for which we need to know the height of the lower + * layout + */ - display->set_colors (r, g, b, a); + if (_left_layout) { - if (supplemental_right) { - supplemental_right->set_colors (r,g,b,a); - supplemental_left->set_colors (r,g,b,a); - } + int w; - r = eg.get_red_p (); - g = eg.get_green_p (); - b = eg.get_blue_p (); - a = 1.0; + font.set_size ((int) lrint (font.get_size() * info_font_scale_factor)); + font.set_weight (Pango::WEIGHT_NORMAL); + tmp->set_font_description (font); - display->set_edit_colors (r, g, b, a); + /* we only care about height, so put as much stuff in here + as possible that might change the height. + */ + tmp->set_text ("qyhH|"); /* one ascender, one descender */ + + tmp->get_pixel_size (w, info_height); + + info_height += 4; - if (supplemental_right) { - supplemental_right->set_edit_colors (r,g,b,a); - supplemental_left->set_edit_colors (r,g,b,a); + req->height += info_height; + req->height += separator_height; } +} - queue_draw (); +void +AudioClock::show_edit_status (int length) +{ + editing_attr->set_start_index (edit_string.length() - length); + editing_attr->set_end_index (edit_string.length()); + + editing_attributes.change (*background_attr); + editing_attributes.change (*foreground_attr); + editing_attributes.change (*editing_attr); + + _layout->set_attributes (editing_attributes); } void -AudioClock::focus () +AudioClock::start_edit () { + edit_string = _layout->get_text (); + pre_edit_string = edit_string; + input_string.clear (); + editing = true; + + show_edit_status (1); + + Keyboard::magic_widget_grab_focus (); + grab_focus (); } void -AudioClock::end_edit () +AudioClock::end_edit (bool modify) { - display->stop_editing (); - editing_field = (Field) 0; - key_entry_state = 0; + if (modify) { + + bool ok = true; + + switch (_mode) { + case Timecode: + ok = timecode_validate_edit (edit_string); + break; + + case BBT: + ok = bbt_validate_edit (edit_string); + break; + + case MinSec: + break; + + case Frames: + break; + } + + if (!ok) { + edit_string = pre_edit_string; + input_string.clear (); + _layout->set_text (edit_string); + } else { + editing = false; + _layout->set_attributes (normal_attributes); + ValueChanged(); /* EMIT_SIGNAL */ + } - /* move focus back to the default widget in the top level window */ + } else { + editing = false; + _layout->set_text (pre_edit_string); + } - Keyboard::magic_widget_drop_focus (); + queue_draw (); - Widget* top = get_toplevel(); + if (!editing) { - if (top->is_toplevel ()) { - Window* win = dynamic_cast<Window*> (top); - win->grab_focus (); + /* move focus back to the default widget in the top level window */ + + Keyboard::magic_widget_drop_focus (); + + Widget* top = get_toplevel(); + + if (top->is_toplevel ()) { + Window* win = dynamic_cast<Window*> (top); + win->grab_focus (); + } } } void -AudioClock::on_realize () +AudioClock::session_configuration_changed (std::string p) { - VBox::on_realize (); + if (p != "timecode-offset" && p != "timecode-offset-negative") { + return; + } - /* styles are not available until the widgets are bound to a window */ - - set_theme (); + framecnt_t current; + + switch (_mode) { + case Timecode: + if (is_duration) { + current = current_duration (); + } else { + current = current_time (); + } + set (current, true); + break; + default: + break; + } } void @@ -343,35 +478,42 @@ AudioClock::set (framepos_t when, bool force, framecnt_t offset, char which) } if (which == 'p' && pdelta && !last_pdelta) { - set_widget_name("TransportClockDisplayDelta"); + set_name("TransportClockDisplayDelta"); last_pdelta = true; } else if (which == 'p' && !pdelta && last_pdelta) { - set_widget_name("TransportClockDisplay"); + set_name("TransportClockDisplay"); last_pdelta = false; } else if (which == 's' && sdelta && !last_sdelta) { - set_widget_name("SecondaryClockDisplayDelta"); + set_name("SecondaryClockDisplayDelta"); last_sdelta = true; } else if (which == 's' && !sdelta && last_sdelta) { - set_widget_name("SecondaryClockDisplay"); + set_name("SecondaryClockDisplay"); last_sdelta = false; } - switch (_mode) { - case Timecode: - set_timecode (when, force); - break; - - case BBT: - set_bbt (when, force); - break; + if (!editing) { - case MinSec: - set_minsec (when, force); - break; + switch (_mode) { + case Timecode: + set_timecode (when, force); + break; + + case BBT: + set_bbt (when, force); + break; + + case MinSec: + set_minsec (when, force); + break; + + case Frames: + set_frames (when, force); + break; + } + } - case Frames: - set_frames (when, force); - break; + if (when != last_when || force) { + queue_draw (); } last_when = when; @@ -382,49 +524,27 @@ AudioClock::set (framepos_t when, bool force, framecnt_t offset, char which) } void -AudioClock::session_configuration_changed (std::string p) -{ - if (p != "timecode-offset" && p != "timecode-offset-negative") { - return; - } - - framecnt_t current; - - switch (_mode) { - case Timecode: - if (is_duration) { - current = current_duration (); - } else { - current = current_time (); - } - set (current, true); - break; - default: - break; - } -} - -void AudioClock::set_frames (framepos_t when, bool /*force*/) { char buf[32]; - snprintf (buf, sizeof (buf), "%" PRId64, when); if (_off) { - display->set_text (_text_cells[AudioFrames], "-----------"); + /* XXX with cairo, we can do better, surely? */ + + _layout->set_text ("-----------"); - if (supplemental_left) { - supplemental_left->set_text (_text_cells[LowerLeft2], ""); - supplemental_right->set_text (_text_cells[LowerRight2], ""); + if (_left_layout) { + _left_layout->set_text (""); + _right_layout->set_text (""); } return; } - - display->set_text (_text_cells[AudioFrames], buf); + snprintf (buf, sizeof (buf), "%10" PRId64, when); + _layout->set_text (buf); - if (supplemental_left) { + if (_left_layout) { framecnt_t rate = _session->frame_rate(); if (fmod (rate, 1000.0) == 0.000) { @@ -433,15 +553,15 @@ AudioClock::set_frames (framepos_t when, bool /*force*/) sprintf (buf, "%" PRId64, rate); } - supplemental_left->set_text (_text_cells[LowerLeft2], buf); + _left_layout->set_text (buf); float vid_pullup = _session->config.get_video_pullup(); if (vid_pullup == 0.0) { - supplemental_right->set_text (_text_cells[LowerRight2], _("none")); + _right_layout->set_text (_("none")); } else { sprintf (buf, "%-6.4f", vid_pullup); - supplemental_right->set_text (_text_cells[LowerRight2], buf); + _right_layout->set_text (buf); } } } @@ -457,14 +577,11 @@ AudioClock::set_minsec (framepos_t when, bool force) int millisecs; if (_off) { - display->set_text (_text_cells[MS_Hours], "--"); - display->set_text (_text_cells[MS_Minutes], "--"); - display->set_text (_text_cells[MS_Seconds], "--"); - display->set_text (_text_cells[MS_Milliseconds], "--"); - - if (supplemental_left) { - supplemental_left->set_text (_text_cells[LowerLeft2], ""); - supplemental_right->set_text (_text_cells[LowerRight2], ""); + _layout->set_text ("--:--:--"); + + if (_left_layout) { + _left_layout->set_text (""); + _right_layout->set_text (""); } return; @@ -479,29 +596,8 @@ AudioClock::set_minsec (framepos_t when, bool force) left -= (framecnt_t) floor (secs * _session->frame_rate()); millisecs = floor (left * 1000.0 / (float) _session->frame_rate()); - if (force || hrs != ms_last_hrs) { - sprintf (buf, "%02d", hrs); - display->set_text (_text_cells[MS_Hours], buf); - ms_last_hrs = hrs; - } - - if (force || mins != ms_last_mins) { - sprintf (buf, "%02d", mins); - display->set_text (_text_cells[MS_Minutes], buf); - ms_last_mins = mins; - } - - if (force || secs != ms_last_secs) { - sprintf (buf, "%02d", secs); - display->set_text (_text_cells[MS_Seconds], buf); - ms_last_secs = secs; - } - - if (force || millisecs != ms_last_millisecs) { - sprintf (buf, "%03d", millisecs); - display->set_text (_text_cells[MS_Milliseconds], buf); - ms_last_millisecs = millisecs; - } + snprintf (buf, sizeof (buf), "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%03" PRIu32, hrs, mins, secs, millisecs); + _layout->set_text (buf); } void @@ -509,17 +605,12 @@ AudioClock::set_timecode (framepos_t when, bool force) { char buf[32]; Timecode::Time TC; - + if (_off) { - display->set_text (_text_cells[Timecode_Sign], ""); - display->set_text (_text_cells[Timecode_Hours], "--"); - display->set_text (_text_cells[Timecode_Minutes], "--"); - display->set_text (_text_cells[Timecode_Seconds], "--"); - display->set_text (_text_cells[Timecode_Frames], "--"); - - if (supplemental_left) { - supplemental_left->set_text (_text_cells[LowerLeft2], ""); - supplemental_right->set_text (_text_cells[LowerRight2], ""); + _layout->set_text ("--:--:--:--"); + if (_left_layout) { + _left_layout->set_text (""); + _right_layout->set_text (""); } return; @@ -530,48 +621,25 @@ AudioClock::set_timecode (framepos_t when, bool force) } else { _session->timecode_time (when, TC); } - - if (force || TC.hours != last_hrs || TC.negative != last_negative) { - if (TC.negative) { - display->set_text (_text_cells[Timecode_Sign], "-"); - sprintf (buf, "%0*" PRIu32, field_length[Timecode_Hours], TC.hours); - } else { - display->set_text (_text_cells[Timecode_Sign], " "); - sprintf (buf, "%0*" PRIu32, field_length[Timecode_Hours], TC.hours); - } - 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); - 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); - display->set_text (_text_cells[Timecode_Seconds], buf); - last_secs = TC.seconds; + + if (TC.negative) { + snprintf (buf, sizeof (buf), "-%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, TC.hours, TC.minutes, TC.seconds, TC.frames); + } else { + snprintf (buf, sizeof (buf), " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, TC.hours, TC.minutes, TC.seconds, TC.frames); } - if (force || TC.frames != last_frames) { - sprintf (buf, "%0*" PRIu32, field_length[Timecode_Frames], TC.frames); - display->set_text (_text_cells[Timecode_Frames], buf); - last_frames = TC.frames; - } + _layout->set_text (buf); - if (supplemental_right) { + if (_right_layout) { double timecode_frames = _session->timecode_frames_per_second(); if (fmod(timecode_frames, 1.0) == 0.0) { - sprintf (buf, "%u %s", int (timecode_frames), (_session->timecode_drop_frames() ? "D" : "")); + sprintf (buf, "FPS %u %s", int (timecode_frames), (_session->timecode_drop_frames() ? "D" : "")); } else { sprintf (buf, "%.2f %s", timecode_frames, (_session->timecode_drop_frames() ? "D" : "")); } - supplemental_right->set_text (_text_cells[LowerRight2], buf); + _right_layout->set_text (buf); } } @@ -582,15 +650,11 @@ AudioClock::set_bbt (framepos_t when, bool force) Timecode::BBT_Time BBT; if (_off) { - display->set_text (_text_cells[Bars], "--"); - display->set_text (_text_cells[Beats], "--"); - display->set_text (_text_cells[Ticks], "--"); - - if (supplemental_left) { - supplemental_left->set_text (_text_cells[LowerLeft2], ""); - supplemental_right->set_text (_text_cells[LowerRight2], ""); + _layout->set_text ("--|--|--"); + if (_left_layout) { + _left_layout->set_text (""); + _right_layout->set_text (""); } - return; } @@ -609,20 +673,10 @@ AudioClock::set_bbt (framepos_t when, bool force) _session->tempo_map().bbt_time (when, BBT); } - sprintf (buf, "%0*" PRIu32, field_length[Bars], BBT.bars); - if (force || _text_cells[Bars]->get_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) { - display->set_text (_text_cells[Beats], buf); - } - sprintf (buf, "%0*" PRIu32, field_length[Ticks], BBT.ticks); - if (force || _text_cells[Ticks]->get_text () != buf) { - display->set_text (_text_cells[Ticks], buf); - } - - if (supplemental_right) { + snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%04" PRIu32, BBT.bars, BBT.beats, BBT.ticks); + _layout->set_text (buf); + + if (_right_layout) { framepos_t pos; if (bbt_reference_time < 0) { @@ -634,10 +688,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()); - supplemental_left->set_text (_text_cells[LowerLeft2], buf); + _left_layout->set_text (buf); sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor()); - supplemental_right->set_text (_text_cells[LowerRight2], buf); + _right_layout->set_text (buf); } } @@ -674,80 +728,10 @@ AudioClock::set_session (Session *s) } } -void -AudioClock::edit_next_field () -{ - /* move on to the next field. - */ - - switch (editing_field) { - - /* Timecode */ - - case Timecode_Hours: - editing_field = Timecode_Minutes; - display->start_editing (_text_cells[Timecode_Minutes]); - break; - case Timecode_Minutes: - editing_field = Timecode_Seconds; - display->start_editing (_text_cells[Timecode_Seconds]); - break; - case Timecode_Seconds: - editing_field = Timecode_Frames; - display->start_editing (_text_cells[Timecode_Frames]); - break; - case Timecode_Frames: - end_edit (); - break; - - /* Min:Sec */ - - case MS_Hours: - editing_field = MS_Minutes; - display->start_editing (_text_cells[MS_Minutes]); - break; - case MS_Minutes: - editing_field = MS_Seconds; - display->start_editing (_text_cells[MS_Seconds]); - break; - case MS_Seconds: - editing_field = MS_Milliseconds; - display->start_editing (_text_cells[MS_Milliseconds]); - break; - case MS_Milliseconds: - end_edit (); - break; - - /* BBT */ - - case Bars: - editing_field = Beats; - display->start_editing (_text_cells[Beats]); - break; - case Beats: - editing_field = Ticks; - display->start_editing (_text_cells[Ticks]); - break; - case Ticks: - end_edit (); - break; - - /* audio frames */ - case AudioFrames: - end_edit (); - break; - - default: - break; - } - - key_entry_state = 0; -} - bool AudioClock::on_key_press_event (GdkEventKey* ev) { - if (editing_field == 0) { + if (!editing) { return false; } @@ -791,19 +775,12 @@ AudioClock::on_key_press_event (GdkEventKey* ev) bool AudioClock::on_key_release_event (GdkEventKey *ev) { - if (editing_field == 0) { - return false; - } - - CairoTextCell *cell = _text_cells[editing_field]; - - if (!cell) { + if (!editing) { return false; } string new_text; char new_char = 0; - bool move_on = false; switch (ev->keyval) { case GDK_0: @@ -847,24 +824,15 @@ AudioClock::on_key_release_event (GdkEventKey *ev) new_char = '9'; break; - case GDK_period: - case GDK_comma: - case GDK_KP_Decimal: - if (_mode == MinSec && editing_field == MS_Seconds) { - new_char = '.'; // XXX i18n - } else { - return false; - } - break; - case GDK_Tab: case GDK_Return: case GDK_KP_Enter: - move_on = true; + end_edit (true); + return true; break; case GDK_Escape: - end_edit (); + end_edit (false); ChangeAborted(); /* EMIT SIGNAL */ return true; @@ -872,132 +840,136 @@ AudioClock::on_key_release_event (GdkEventKey *ev) return false; } - if (!move_on) { - - if (key_entry_state == 0) { - - /* initialize with a fresh new string */ + if (input_string.length() >= insert_max) { + /* eat the key event, but do no nothing with it */ + return true; + } - if (editing_field != AudioFrames) { - for (uint32_t xn = 0; xn < field_length[editing_field] - 1; ++xn) { - new_text += '0'; + input_string.insert (input_string.begin(), new_char); + + string::reverse_iterator ri; + vector<int> insert_at; + int highlight_length; + + /* merge with pre-edit-string into edit string */ + + switch (_mode) { + case Frames: + edit_string = input_string; + highlight_length = edit_string.length(); + break; + + default: + edit_string = pre_edit_string; + + /* backup through the original string, till we have + * enough digits locations to put all the digits from + * the input string. + */ + + for (ri = edit_string.rbegin(); ri != edit_string.rend(); ++ri) { + if (isdigit (*ri)) { + insert_at.push_back (edit_string.length() - (ri - edit_string.rbegin()) - 1); + if (insert_at.size() == input_string.length()) { + break; } - } else { - new_text = ""; } - + } + + if (insert_at.size() != input_string.length()) { + error << "something went wrong " << endmsg; } else { - - string existing = cell->get_text(); - if (existing.length() >= field_length[editing_field]) { - new_text = existing.substr (1, field_length[editing_field] - 1); - } else { - new_text = existing.substr (0, field_length[editing_field] - 1); + for (int i = input_string.length() - 1; i >= 0; --i) { + edit_string[insert_at[i]] = input_string[i]; } + + highlight_length = edit_string.length() - insert_at.back(); } - - new_text += new_char; - display->set_text (cell, new_text); - _canonical_time_is_displayed = true; - key_entry_state++; - } - - if (key_entry_state == field_length[editing_field]) { - move_on = true; + + break; } + + if (edit_string != _layout->get_text()) { + show_edit_status (highlight_length); + _layout->set_text (edit_string); + queue_draw (); + } - if (move_on) { - - if (key_entry_state) { - - /* if key_entry_state != then we edited the text - */ - - char buf[16]; + return true; +} - switch (editing_field) { - case Timecode_Hours: - case Timecode_Minutes: - case Timecode_Seconds: - case Timecode_Frames: - // Check Timecode fields for sanity (may also adjust fields) - timecode_sanitize_display(); - break; - case Bars: - case Beats: - case Ticks: - // 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); - 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); - display->set_text (_text_cells[Beats], buf); - _canonical_time_is_displayed = true; - } - break; - default: - break; - } +AudioClock::Field +AudioClock::index_to_field (int index) const +{ + switch (_mode) { + case Timecode: + if (index < 4) { + return Timecode_Hours; + } else if (index < 7) { + return Timecode_Minutes; + } else if (index < 10) { + return Timecode_Seconds; + } else if (index < 13) { + return Timecode_Frames; + } else { + return Field (0); + } + break; + case BBT: + if (index < 5) { + return Bars; + } else if (index < 7) { + return Beats; + } else if (index < 12) { + return Ticks; + } else { + return Field (0); + } + break; - ValueChanged(); /* EMIT_SIGNAL */ + case MinSec: + if (index < 3) { + return Timecode_Hours; + } else if (index < 6) { + return MS_Minutes; + } else if (index < 9) { + return MS_Seconds; + } else if (index < 12) { + return MS_Milliseconds; + } else { + return Field (0); } - - edit_next_field (); - } + break; - //if user hit Enter, lose focus - switch (ev->keyval) { - case GDK_Return: - case GDK_KP_Enter: - end_edit (); + case Frames: + return AudioFrames; + break; } - - return true; } bool -AudioClock::button_press (GdkEventButton *ev, CairoCell* cell) +AudioClock::on_button_press_event (GdkEventButton *ev) { switch (ev->button) { case 1: if (editable) { - if (cell) { - Field f = (Field) cell->id (); - switch (f) { - case Timecode_Hours: - case Timecode_Minutes: - case Timecode_Seconds: - case Timecode_Frames: - case MS_Hours: - case MS_Minutes: - case MS_Seconds: - case MS_Milliseconds: - case Bars: - case Beats: - case Ticks: - case AudioFrames: - editing_field = f; - display->start_editing (cell); - break; - default: - return false; - } - } - - Keyboard::magic_widget_grab_focus (); - + dragging = true; /* make absolutely sure that the pointer is grabbed */ gdk_pointer_grab(ev->window,false , GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), NULL,NULL,ev->time); - dragging = true; drag_accum = 0; drag_start_y = ev->y; drag_y = ev->y; + + int index; + int trailing; + + if (_layout->xy_to_index (ev->x * PANGO_SCALE, ev->y * PANGO_SCALE, index, trailing)) { + drag_field = index_to_field (index); + } else { + drag_field = Field (0); + } } break; @@ -1010,16 +982,22 @@ AudioClock::button_press (GdkEventButton *ev, CairoCell* cell) } bool -AudioClock::button_release (GdkEventButton *ev, CairoCell*) +AudioClock::on_button_release_event (GdkEventButton *ev) { if (editable) { if (dragging) { gdk_pointer_ungrab (GDK_CURRENT_TIME); dragging = false; if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){ - // we actually dragged so return without setting editing focus, or we shift clicked + // we actually dragged so return without + // setting editing focus, or we shift clicked return true; + } else { + if (ev->button == 1) { + start_edit (); + } } + } } @@ -1035,39 +1013,27 @@ AudioClock::button_release (GdkEventButton *ev, CairoCell*) } bool -AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell) +AudioClock::on_scroll_event (GdkEventScroll *ev) { + int index; + int trailing; + if (_session == 0 || !editable) { return false; } - if (cell) { - Field f = (Field) cell->id (); - switch (f) { - case Timecode_Hours: - case Timecode_Minutes: - case Timecode_Seconds: - case Timecode_Frames: - case MS_Hours: - case MS_Minutes: - case MS_Seconds: - case MS_Milliseconds: - case Bars: - case Beats: - case Ticks: - case AudioFrames: - break; - default: - return false; - } + if (!_layout->xy_to_index (ev->x * PANGO_SCALE, ev->y * PANGO_SCALE, index, trailing)) { + /* not in the main layout */ + return false; } - + + Field f = index_to_field (index); framepos_t frames = 0; switch (ev->direction) { case GDK_SCROLL_UP: - frames = get_frames ((Field) cell->id()); + frames = get_frame_step (f); if (frames != 0) { if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; @@ -1078,7 +1044,7 @@ AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell) break; case GDK_SCROLL_DOWN: - frames = get_frames ((Field) cell->id()); + frames = get_frame_step (f); if (frames != 0) { if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; @@ -1103,7 +1069,7 @@ AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell) } bool -AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) +AudioClock::on_motion_notify_event (GdkEventMotion *ev) { if (_session == 0 || !dragging) { return false; @@ -1111,7 +1077,6 @@ AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) float pixel_frame_scale_factor = 0.2f; -/* if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { pixel_frame_scale_factor = 0.1f; } @@ -1122,42 +1087,37 @@ AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) pixel_frame_scale_factor = 0.025f; } -*/ + double y_delta = ev->y - drag_y; drag_accum += y_delta*pixel_frame_scale_factor; drag_y = ev->y; - if (trunc(drag_accum) != 0) { + if (trunc (drag_accum) != 0) { framepos_t frames; framepos_t pos; int dir; dir = (drag_accum < 0 ? 1:-1); pos = current_time(); - frames = get_frames (field,pos,dir); + frames = get_frame_step (drag_field,pos,dir); if (frames != 0 && frames * drag_accum < current_time()) { - - set ((framepos_t) floor (pos - drag_accum * frames), false); // minus because up is negative in computer-land - + set ((framepos_t) floor (pos - drag_accum * frames), false); // minus because up is negative in GTK } else { set (0 , false); - } drag_accum= 0; ValueChanged(); /* EMIT_SIGNAL */ - - } return true; } framepos_t -AudioClock::get_frames (Field field, framepos_t pos, int dir) +AudioClock::get_frame_step (Field field, framepos_t pos, int dir) { framecnt_t f = 0; Timecode::BBT_Time BBT; @@ -1222,9 +1182,9 @@ AudioClock::get_frames (Field field, framepos_t pos, int dir) framepos_t AudioClock::current_time (framepos_t pos) const { - if (!_canonical_time_is_displayed) { - return _canonical_time; - } + // if (!_canonical_time_is_displayed) { + // return _canonical_time; + //} framepos_t ret = 0; @@ -1273,62 +1233,49 @@ AudioClock::current_duration (framepos_t pos) const return ret; } -void -AudioClock::timecode_sanitize_display() +bool +AudioClock::bbt_validate_edit (const string& str) { - // Check Timecode fields for sanity, possibly adjusting values - if (atoi (_text_cells[Timecode_Minutes]->get_text()) > 59) { - display->set_text (_text_cells[Timecode_Minutes], "59"); - _canonical_time_is_displayed = true; + AnyTime any; + + sscanf (str.c_str(), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, &any.bbt.bars, &any.bbt.beats, &any.bbt.ticks); + + if (!is_duration && any.bbt.bars == 0) { + return false; } - if (atoi (_text_cells[Timecode_Seconds]->get_text()) > 59) { - display->set_text (_text_cells[Timecode_Seconds], "59"); - _canonical_time_is_displayed = true; + if (!is_duration && any.bbt.beats == 0) { + return false; } - switch ((long)rint(_session->timecode_frames_per_second())) { - case 24: - if (atoi (_text_cells[Timecode_Frames]->get_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) { - 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) { - display->set_text (_text_cells[Timecode_Frames], "29"); - _canonical_time_is_displayed = true; - } - break; - default: - break; + return true; +} + +bool +AudioClock::timecode_validate_edit (const string& str) +{ + Timecode::Time TC; + + if (sscanf (_layout->get_text().c_str(), "%" PRId32 ":%" PRId32 ":%" PRId32 ":%" PRId32, + &TC.hours, &TC.minutes, &TC.seconds, &TC.frames) != 4) { + return false; + } + + if (TC.minutes > 59 || TC.seconds > 59) { + return false; + } + + if (TC.frames > (long)rint(_session->timecode_frames_per_second()) - 1) { + return false; } 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)) { - display->set_text (_text_cells[Timecode_Frames], "02"); - _canonical_time_is_displayed = true; + if (TC.minutes % 10 && TC.seconds == 0 && TC.frames < 2) { + return false; } } -} - -/** This is necessary because operator[] isn't const with std::map. - * @param f Field. - * @return Label widget. - */ -CairoTextCell* -AudioClock::label (Field f) const -{ - std::map<Field,CairoTextCell*>::const_iterator i = _text_cells.find (f); - assert (i != _text_cells.end ()); - return i->second; + return true; } framepos_t @@ -1341,21 +1288,222 @@ AudioClock::timecode_frame_from_display () const Timecode::Time TC; framepos_t sample; - if (!label (Timecode_Sign)->get_text().empty()) { - TC.hours = atoi (label (Timecode_Hours)->get_text()); - } else { - TC.hours = -atoi (label (Timecode_Hours)->get_text()); - } + sscanf (_layout->get_text().c_str(), "%d:%d:%d:%d", &TC.hours, &TC.minutes, &TC.seconds, &TC.frames); - TC.minutes = atoi (label (Timecode_Minutes)->get_text()); - TC.seconds = atoi (label (Timecode_Seconds)->get_text()); - TC.frames = atoi (label (Timecode_Frames)->get_text()); TC.rate = _session->timecode_frames_per_second(); TC.drop= _session->timecode_drop_frames(); _session->timecode_to_sample (TC, sample, false /* use_offset */, false /* use_subframes */ ); + + // timecode_tester (); + + return sample; +} + +framepos_t +AudioClock::minsec_frame_from_display () const +{ + if (_session == 0) { + return 0; + } + + int hrs, mins, secs, millisecs; + framecnt_t sr = _session->frame_rate(); + + sscanf (_layout->get_text().c_str(), "%d:%d:%d:%d", &hrs, &mins, &secs, &millisecs); + return (framepos_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr) + (millisecs * sr / 1000.0)); +} + +framepos_t +AudioClock::bbt_frame_from_display (framepos_t pos) const +{ + if (_session == 0) { + error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; + return 0; + } + + AnyTime any; + any.type = AnyTime::BBT; + + sscanf (_layout->get_text().c_str(), "%" PRId32 "|%" PRId32 "|%" PRId32, &any.bbt.bars, &any.bbt.beats, &any.bbt.ticks); + + if (is_duration) { + any.bbt.bars++; + any.bbt.beats++; + return _session->any_duration_to_frames (pos, any); + } else { + return _session->convert_to_frames (any); + } +} + + +framepos_t +AudioClock::bbt_frame_duration_from_display (framepos_t pos) const +{ + if (_session == 0) { + error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; + return 0; + } + + Timecode::BBT_Time bbt; + + sscanf (_layout->get_text().c_str(), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, &bbt.bars, &bbt.beats, &bbt.ticks); + + return _session->tempo_map().bbt_duration_at(pos,bbt,1); +} + +framepos_t +AudioClock::audio_frame_from_display () const +{ + framepos_t f; + sscanf (_layout->get_text().c_str(), "%" PRId64, &f); + return f; +} + +void +AudioClock::build_ops_menu () +{ + using namespace Menu_Helpers; + ops_menu = new Menu; + MenuList& ops_items = ops_menu->items(); + ops_menu->set_name ("ArdourContextMenu"); + + if (!Profile->get_sae()) { + ops_items.push_back (MenuElem (_("Timecode"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Timecode))); + } + ops_items.push_back (MenuElem (_("Bars:Beats"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), BBT))); + ops_items.push_back (MenuElem (_("Minutes:Seconds"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), MinSec))); + ops_items.push_back (MenuElem (_("Samples"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Frames))); + + if (editable && !is_duration && !_follows_playhead) { + ops_items.push_back (SeparatorElem()); + ops_items.push_back (MenuElem (_("Set From Playhead"), sigc::mem_fun(*this, &AudioClock::set_from_playhead))); + ops_items.push_back (MenuElem (_("Locate to This Time"), sigc::mem_fun(*this, &AudioClock::locate))); + } +} + +void +AudioClock::set_from_playhead () +{ + if (!_session) { + return; + } + + set (_session->transport_frame()); + ValueChanged (); +} + +void +AudioClock::locate () +{ + if (!_session || is_duration) { + return; + } + + _session->request_locate (current_time(), _session->transport_rolling ()); +} + +void +AudioClock::set_mode (Mode m) +{ + if (_mode == m) { + return; + } + + _mode = m; + + switch (_mode) { + case Timecode: + insert_max = 9; // 8 digits + sign [-]2:2:2:2 + mode_based_info_ratio = 0.5; + break; + + case BBT: + insert_max = 8; // 8 digits, 2|2|4 + mode_based_info_ratio = 0.5; + break; + + case MinSec: + insert_max = 9; // 7 digits 2:2:2.3 + mode_based_info_ratio = 1.0; + break; + + case Frames: + insert_max = INT_MAX; + mode_based_info_ratio = 1.0; + break; + } + + set (last_when, true); + + if (!is_transient) { + ModeChanged (); /* EMIT SIGNAL (the static one)*/ + } + + mode_changed (); /* EMIT SIGNAL (the member one) */ +} + +void +AudioClock::set_bbt_reference (framepos_t pos) +{ + bbt_reference_time = pos; +} + +void +AudioClock::on_style_changed (const Glib::RefPtr<Gtk::Style>& old_style) +{ + CairoWidget::on_style_changed (old_style); + set_font (); + set_colors (); +} + +void +AudioClock::set_is_duration (bool yn) +{ + if (yn == is_duration) { + return; + } + + is_duration = yn; + set (last_when, true, 0, 's'); +} + +void +AudioClock::set_off (bool yn) +{ + if (_off == yn) { + return; + } + + _off = yn; + + if (_off) { + _canonical_time = current_time (); + _canonical_time_is_displayed = false; + } else { + _canonical_time_is_displayed = true; + } + + /* force a possible redraw */ + + set (_canonical_time, true); +} + +void +AudioClock::focus () +{ + start_edit (); +} +void +AudioClock::set_draw_background (bool yn) +{ + _need_bg = yn; +} +void +AudioClock::timecode_tester () +{ #if 0 #define Timecode_SAMPLE_TEST_1 #define Timecode_SAMPLE_TEST_2 @@ -1725,297 +1873,4 @@ AudioClock::timecode_frame_from_display () const #endif #endif - - return sample; -} - -framepos_t -AudioClock::minsec_frame_from_display () const -{ - if (_session == 0) { - return 0; - } - - int hrs = atoi (label (MS_Hours)->get_text()); - int mins = atoi (label (MS_Minutes)->get_text()); - int secs = atoi (label (MS_Seconds)->get_text()); - int millisecs = atoi (label (MS_Milliseconds)->get_text()); - - framecnt_t sr = _session->frame_rate(); - - return (framepos_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr) + (millisecs * sr / 1000.0)); -} - -framepos_t -AudioClock::bbt_frame_from_display (framepos_t pos) const -{ - if (_session == 0) { - error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; - return 0; - } - - AnyTime any; - any.type = AnyTime::BBT; - - any.bbt.bars = atoi (label (Bars)->get_text()); - any.bbt.beats = atoi (label (Beats)->get_text()); - any.bbt.ticks = atoi (label (Ticks)->get_text()); - - if (is_duration) { - any.bbt.bars++; - any.bbt.beats++; - return _session->any_duration_to_frames (pos, any); - } else { - return _session->convert_to_frames (any); - } -} - - -framepos_t -AudioClock::bbt_frame_duration_from_display (framepos_t pos) const -{ - if (_session == 0) { - error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; - return 0; - } - - Timecode::BBT_Time bbt; - - - bbt.bars = atoi (label (Bars)->get_text()); - bbt.beats = atoi (label (Beats)->get_text()); - bbt.ticks = atoi (label (Ticks)->get_text()); - - return _session->tempo_map().bbt_duration_at(pos,bbt,1); -} - -framepos_t -AudioClock::audio_frame_from_display () const -{ - return (framepos_t) atoi (label (AudioFrames)->get_text ()); -} - -void -AudioClock::build_ops_menu () -{ - using namespace Menu_Helpers; - ops_menu = new Menu; - MenuList& ops_items = ops_menu->items(); - ops_menu->set_name ("ArdourContextMenu"); - - if (!Profile->get_sae()) { - ops_items.push_back (MenuElem (_("Timecode"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Timecode))); - } - ops_items.push_back (MenuElem (_("Bars:Beats"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), BBT))); - ops_items.push_back (MenuElem (_("Minutes:Seconds"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), MinSec))); - ops_items.push_back (MenuElem (_("Samples"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Frames))); - - if (editable && !is_duration && !_follows_playhead) { - ops_items.push_back (SeparatorElem()); - ops_items.push_back (MenuElem (_("Set From Playhead"), sigc::mem_fun(*this, &AudioClock::set_from_playhead))); - ops_items.push_back (MenuElem (_("Locate to This Time"), sigc::mem_fun(*this, &AudioClock::locate))); - } -} - -void -AudioClock::set_from_playhead () -{ - if (!_session) { - return; - } - - set (_session->transport_frame()); - ValueChanged (); -} - -void -AudioClock::locate () -{ - if (!_session || is_duration) { - return; - } - - _session->request_locate (current_time(), _session->transport_rolling ()); -} - -void -AudioClock::connect_signals () -{ - 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) -{ - if (_mode == m) { - return; - } - - _mode = m; - - display->clear_cells (); - - if (supplemental_left) { - supplemental_left->clear_cells (); - supplemental_right->clear_cells (); - } - - switch (_mode) { - case Timecode: - display->add_cell (_text_cells[Timecode_Sign]); - 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: - 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], 2); // why not 1? M is too wide - supplemental_right->set_width_chars (_text_cells[LowerRight2], 5); - - supplemental_left->set_text (_text_cells[LowerLeft1], _("T")); - supplemental_right->set_text (_text_cells[LowerRight1], _("M")); - } - break; - - case MinSec: - 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]); - 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]); - - /* These are going to remain empty */ - - supplemental_left->set_width_chars (_text_cells[LowerLeft1], 1); - supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5); - - supplemental_right->set_width_chars (_text_cells[LowerRight1], 1); - supplemental_right->set_width_chars (_text_cells[LowerRight2], 1); - - supplemental_left->set_text (_text_cells[LowerLeft1], _(" ")); - supplemental_right->set_text (_text_cells[LowerRight1], _(" ")); - } - break; - - case Frames: - 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; - } - - if (supplemental_left) { - /* clear information cells */ - supplemental_left->set_text (_text_cells[LowerLeft2], _("")); - supplemental_right->set_text (_text_cells[LowerRight2], _("")); - } - - set (last_when, true); - - if (!is_transient) { - ModeChanged (); /* EMIT SIGNAL (the static one)*/ - } - - mode_changed (); /* EMIT SIGNAL (the member one) */ -} - -void -AudioClock::set_bbt_reference (framepos_t pos) -{ - bbt_reference_time = pos; -} - -void -AudioClock::on_style_changed (const Glib::RefPtr<Gtk::Style>& old_style) -{ - VBox::on_style_changed (old_style); - set_theme (); -} - -void -AudioClock::set_is_duration (bool yn) -{ - if (yn == is_duration) { - return; - } - - is_duration = yn; - set (last_when, true, 0, 's'); -} - -void -AudioClock::set_off (bool yn) -{ - if (_off == yn) { - return; - } - - _off = yn; - - if (_off) { - _canonical_time = current_time (); - _canonical_time_is_displayed = false; - } else { - _canonical_time_is_displayed = true; - } - - /* force a possible redraw */ - - set (_canonical_time, true); } diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h index 4ce057b01b..3771cb763d 100644 --- a/gtk2_ardour/audio_clock.h +++ b/gtk2_ardour/audio_clock.h @@ -21,6 +21,9 @@ #define __audio_clock_h__ #include <map> +#include <vector> + +#include <pangomm.h> #include <gtkmm/alignment.h> #include <gtkmm/box.h> @@ -30,15 +33,13 @@ #include "ardour/ardour.h" #include "ardour/session_handle.h" -class CairoEditableText; -class CairoCell; -class CairoTextCell; +#include "cairo_widget.h" namespace ARDOUR { class Session; } -class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr +class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr { public: enum Mode { @@ -55,6 +56,8 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr Mode mode() const { return _mode; } void set_off (bool yn); bool off() const { return _off; } + void set_widget_name (const std::string& name); + void set_active_state (Gtkmm2ext::ActiveState s); void focus (); @@ -64,8 +67,7 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr void set_mode (Mode); void set_bbt_reference (framepos_t); void set_is_duration (bool); - - void set_widget_name (const std::string&); + void set_draw_background (bool yn); std::string name() const { return _name; } @@ -80,15 +82,11 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr static sigc::signal<void> ModeChanged; static std::vector<AudioClock*> clocks; - 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; } + protected: + void render (cairo_t*); private: Mode _mode; - uint32_t key_entry_state; std::string _name; bool is_transient; bool is_duration; @@ -96,13 +94,31 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr /** true if this clock follows the playhead, meaning that certain operations are redundant */ bool _follows_playhead; bool _off; + bool _need_bg; Gtk::Menu *ops_menu; - CairoEditableText* display; + Glib::RefPtr<Pango::Layout> _layout; + Glib::RefPtr<Pango::Layout> _left_layout; + Glib::RefPtr<Pango::Layout> _right_layout; + + Pango::AttrColor* editing_attr; + Pango::AttrColor* background_attr; + Pango::AttrColor* foreground_attr; + + Pango::AttrList normal_attributes; + Pango::AttrList editing_attributes; + Pango::AttrList info_attributes; + + int layout_height; + int layout_width; + int info_height; + int upper_height; + double mode_based_info_ratio; + static const double info_font_scale_factor; + static const double separator_height; enum Field { - Timecode_Sign, Timecode_Hours, Timecode_Minutes, Timecode_Seconds, @@ -115,54 +131,26 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr Beats, Ticks, AudioFrames, - - Colon1, - Colon2, - Colon3, - Bar1, - Bar2, - - LowerLeft1, - LowerLeft2, - LowerRight1, - LowerRight2, }; - /** CairoCells of various kinds for each of our non-text Fields */ - std::map<Field,CairoCell*> _fixed_cells; - /** CairoTextCells for each of our text Fields */ - std::map<Field, CairoTextCell*> _text_cells; - CairoTextCell* label (Field) const; - - Gtk::HBox off_hbox; - - CairoEditableText* supplemental_left; - CairoEditableText* supplemental_right; + Field index_to_field (int index) const; - Gtk::HBox top; - Gtk::HBox bottom; - - Field editing_field; + bool editing; + std::string edit_string; + std::string pre_edit_string; + std::string input_string; + std::string::size_type insert_max; + framepos_t bbt_reference_time; framepos_t last_when; bool last_pdelta; bool last_sdelta; - uint32_t last_hrs; - uint32_t last_mins; - uint32_t last_secs; - uint32_t last_frames; - bool last_negative; - - long ms_last_hrs; - long ms_last_mins; - int ms_last_secs; - int ms_last_millisecs; - bool dragging; double drag_start_y; double drag_y; double drag_accum; + Field drag_field; /** true if the time of this clock is the one displayed in its widgets. * if false, the time in the widgets is an approximation of _canonical_time, @@ -172,32 +160,26 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr framepos_t _canonical_time; void on_realize (); - - bool key_press (GdkEventKey *); - bool key_release (GdkEventKey *); - - /* proxied from CairoEditableText */ - - 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; - - bool field_motion_notify_event (GdkEventMotion *ev, Field); - bool field_focus_in_event (GdkEventFocus *, Field); - bool field_focus_out_event (GdkEventFocus *, Field); - bool drop_focus_handler (GdkEventFocus*); + bool on_key_press_event (GdkEventKey *); + bool on_key_release_event (GdkEventKey *); + bool on_scroll_event (GdkEventScroll *ev); + bool on_button_press_event (GdkEventButton *ev); + bool on_button_release_event(GdkEventButton *ev); + void on_style_changed (const Glib::RefPtr<Gtk::Style>&); + void on_size_request (Gtk::Requisition* req); + bool on_motion_notify_event (GdkEventMotion *ev); + void on_size_allocate (Gtk::Allocation&); void set_timecode (framepos_t, bool); void set_bbt (framepos_t, bool); void set_minsec (framepos_t, bool); void set_frames (framepos_t, bool); - framepos_t get_frames (Field, framepos_t pos = 0, int dir = 1); + framepos_t get_frame_step (Field, framepos_t pos = 0, int dir = 1); + + bool timecode_validate_edit (const std::string&); + bool bbt_validate_edit (const std::string&); - void timecode_sanitize_display(); framepos_t timecode_frame_from_display () const; framepos_t bbt_frame_from_display (framepos_t) const; framepos_t bbt_frame_duration_from_display (framepos_t) const; @@ -208,20 +190,19 @@ class AudioClock : public Gtk::VBox, public ARDOUR::SessionHandlePtr void session_configuration_changed (std::string); - static uint32_t field_length[]; - static bool _has_focus; + Field index_to_field () const; - void on_style_changed (const Glib::RefPtr<Gtk::Style>&); - bool on_key_press_event (GdkEventKey*); - bool on_key_release_event (GdkEventKey*); - - void end_edit (); + void start_edit (); + void end_edit (bool); void edit_next_field (); - void connect_signals (); - void disconnect_signals (); + void set_font (); + void set_colors (); + void show_edit_status (int length); + + void timecode_tester (); - void set_theme (); + double bg_r, bg_g, bg_b, bg_a; }; #endif /* __audio_clock_h__ */ diff --git a/gtk2_ardour/cairo_widget.cc b/gtk2_ardour/cairo_widget.cc index 5f83cb80d5..3bd5ab9fca 100644 --- a/gtk2_ardour/cairo_widget.cc +++ b/gtk2_ardour/cairo_widget.cc @@ -107,6 +107,20 @@ CairoWidget::set_visual_state (Gtkmm2ext::VisualState s) } void +CairoWidget::set_active (bool yn) +{ + /* this is an API simplification for buttons + that only use the Active and Normal states. + */ + + if (yn) { + set_active_state (Gtkmm2ext::Active); + } else { + unset_active_state (); + } +} + +void CairoWidget::on_state_changed (Gtk::StateType) { /* this will catch GTK-level state changes from calls like diff --git a/gtk2_ardour/cairo_widget.h b/gtk2_ardour/cairo_widget.h index d3eac0bb02..dc50762b16 100644 --- a/gtk2_ardour/cairo_widget.h +++ b/gtk2_ardour/cairo_widget.h @@ -36,10 +36,22 @@ public: Gtkmm2ext::ActiveState active_state() const { return _active_state; } Gtkmm2ext::VisualState visual_state() const { return _visual_state; } + + /* derived widgets can override these two to catch + changes in active & visual state + */ + virtual void set_active_state (Gtkmm2ext::ActiveState); virtual void set_visual_state (Gtkmm2ext::VisualState); - virtual void unset_active_state () { set_active_state (Gtkmm2ext::ActiveState (0)); } - virtual void unset_visual_state () { set_visual_state (Gtkmm2ext::VisualState (0)); } + + void unset_active_state () { set_active_state (Gtkmm2ext::ActiveState (0)); } + void unset_visual_state () { set_visual_state (Gtkmm2ext::VisualState (0)); } + + /* this is an API simplification for widgets + that only use the Active and Normal active states. + */ + void set_active (bool); + bool get_active () { return active_state() != Gtkmm2ext::ActiveState (0); } sigc::signal<void> StateChanged; diff --git a/gtk2_ardour/canvas_vars.h b/gtk2_ardour/canvas_vars.h index 06ae244816..7688f0c629 100644 --- a/gtk2_ardour/canvas_vars.h +++ b/gtk2_ardour/canvas_vars.h @@ -188,3 +188,19 @@ BUTTON_VARS(MouseModeButton, "mouse mode button") BUTTON_VARS(ZoomButton, "zoom button") BUTTON_VARS(RouteButton, "route button") +#define CLOCK_VARS(root,name) \ + CANVAS_VARIABLE(canvasvar_ ## root ## Background, name ": background") \ + CANVAS_VARIABLE(canvasvar_ ## root ## Text, name ": text") \ + CANVAS_VARIABLE(canvasvar_ ## root ## EditedText, name ": edited text") \ + CANVAS_VARIABLE(canvasvar_ ## root ## Cursor, name ": cursor") + +CLOCK_VARS(TransportClock, "transport clock") +CLOCK_VARS(SecondaryClock, "secondary clock") +CLOCK_VARS(TransportDeltaClock, "transport delta clock") +CLOCK_VARS(SecondaryDeltaClock, "secondary delta clock") +CLOCK_VARS(BigClock, "big clock") +CLOCK_VARS(BigClockActive, "big clock active") +CLOCK_VARS(PunchClock, "punch clock") +CLOCK_VARS(SelectionClock, "selection clock") +CLOCK_VARS(NudgeClock, "nudge clock") +CLOCK_VARS(GenericClock, "clock") diff --git a/gtk2_ardour/edit_note_dialog.cc b/gtk2_ardour/edit_note_dialog.cc index e334ffa06c..5f3cb16502 100644 --- a/gtk2_ardour/edit_note_dialog.cc +++ b/gtk2_ardour/edit_note_dialog.cc @@ -38,8 +38,8 @@ EditNoteDialog::EditNoteDialog (MidiRegionView* rv, Gnome::Canvas::CanvasNoteEve : ArdourDialog (_("Note")) , _region_view (rv) , _event (ev) - , _time_clock (X_("notetime"), true, X_("NoteTimeClock"), true, false) - , _length_clock (X_("notelength"), true, X_("NoteLengthClock"), true, false, true) + , _time_clock (X_("notetime"), true, "", true, false) + , _length_clock (X_("notelength"), true, "", true, false, true) { Table* table = manage (new Table (4, 2)); table->set_spacings (6); diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 80f7feed72..f5d5370b1f 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -262,7 +262,7 @@ Editor::Editor () /* tool bar related */ - , zoom_range_clock (new AudioClock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, false, true)) + , zoom_range_clock (new AudioClock (X_("zoomrange"), false, X_("zoom range"), true, false, true)) , toolbar_selection_clock_table (2,3) @@ -276,7 +276,7 @@ Editor::Editor () /* nudge */ - , nudge_clock (new AudioClock (X_("nudge"), false, X_("NudgeClock"), true, false, true)) + , nudge_clock (new AudioClock (X_("nudge"), false, X_("nudge"), true, false, true)) , meters_running(false) , _pending_locate_request (false) , _pending_initial_locate (false) diff --git a/gtk2_ardour/export_format_dialog.cc b/gtk2_ardour/export_format_dialog.cc index c8e139acce..1a8ecf8ffa 100644 --- a/gtk2_ardour/export_format_dialog.cc +++ b/gtk2_ardour/export_format_dialog.cc @@ -44,11 +44,11 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) : silence_table (2, 4), trim_start_checkbox (_("Trim silence at start")), silence_start_checkbox (_("Add silence at start:")), - silence_start_clock ("silence_start", true, "PreRollClock", true, false, true), + silence_start_clock ("silence_start", true, "", true, false, true), trim_end_checkbox (_("Trim silence at end")), silence_end_checkbox (_("Add silence at end:")), - silence_end_clock ("silence_end", true, "PreRollClock", true, false, true), + silence_end_clock ("silence_end", true, "", true, false, true), format_table (3, 4), compatibility_label (_("Compatibility"), Gtk::ALIGN_LEFT), diff --git a/gtk2_ardour/insert_time_dialog.cc b/gtk2_ardour/insert_time_dialog.cc index 7bfef4b757..ae0e9a1f8f 100644 --- a/gtk2_ardour/insert_time_dialog.cc +++ b/gtk2_ardour/insert_time_dialog.cc @@ -31,7 +31,7 @@ using namespace Editing; InsertTimeDialog::InsertTimeDialog (PublicEditor& e) : ArdourDialog (_("Insert Time")) , _editor (e) - , _clock ("insertTimeClock", true, X_("InsertTimeClock"), true, false, true, false) + , _clock ("insertTimeClock", true, "", true, false, true, false) { set_session (_editor.session ()); diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc index 004bf9e765..020638d600 100644 --- a/gtk2_ardour/location_ui.cc +++ b/gtk2_ardour/location_ui.cc @@ -47,9 +47,9 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num) : SessionHandlePtr (0) /* explicitly set below */ , location(0) , item_table (1, 6, false) - , start_clock (X_("locationstart"), true, X_("LocationEditRowClock"), true, false) - , end_clock (X_("locationend"), true, X_("LocationEditRowClock"), true, false) - , length_clock (X_("locationlength"), true, X_("LocationEditRowClock"), true, false, true) + , start_clock (X_("locationstart"), true, "", true, false) + , end_clock (X_("locationend"), true, "", true, false) + , length_clock (X_("locationlength"), true, "", true, false, true) , cd_check_button (_("CD")) , hide_check_button (_("Hide")) , lock_check_button (_("Lock")) @@ -136,7 +136,6 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num) start_go_button.signal_clicked().connect(sigc::bind (sigc::mem_fun (*this, &LocationEditRow::go_button_pressed), LocStart)); start_to_playhead_button->signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocStart)); start_clock.ValueChanged.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::clock_changed), LocStart)); - start_clock.ChangeAborted.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::change_aborted), LocStart)); end_hbox.pack_start (end_go_button, false, false); end_hbox.pack_start (end_clock, false, false); @@ -145,10 +144,8 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num) end_go_button.signal_clicked().connect(sigc::bind (sigc::mem_fun (*this, &LocationEditRow::go_button_pressed), LocEnd)); end_to_playhead_button->signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocEnd)); end_clock.ValueChanged.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::clock_changed), LocEnd)); - end_clock.ChangeAborted.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::change_aborted), LocEnd)); length_clock.ValueChanged.connect (sigc::bind ( sigc::mem_fun(*this, &LocationEditRow::clock_changed), LocLength)); - length_clock.ChangeAborted.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::change_aborted), LocLength)); cd_check_button.signal_toggled().connect(sigc::mem_fun(*this, &LocationEditRow::cd_toggled)); hide_check_button.signal_toggled().connect(sigc::mem_fun(*this, &LocationEditRow::hide_toggled)); @@ -457,14 +454,6 @@ LocationEditRow::clock_changed (LocationPart part) } void -LocationEditRow::change_aborted (LocationPart /*part*/) -{ - if (i_am_the_modifier || !location) return; - - set_location(location); -} - -void LocationEditRow::cd_toggled () { if (i_am_the_modifier || !location) { diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h index 9637257f49..eef33b161f 100644 --- a/gtk2_ardour/location_ui.h +++ b/gtk2_ardour/location_ui.h @@ -119,7 +119,6 @@ class LocationEditRow : public Gtk::HBox, public ARDOUR::SessionHandlePtr void go_button_pressed (LocationPart part); void clock_changed (LocationPart part); - void change_aborted (LocationPart part); void cd_toggled (); void hide_toggled (); diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index 50feba3484..040adc2db9 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -195,7 +195,7 @@ FaderOption::add_to_page (OptionEditorPage* p) ClockOption::ClockOption (string const & i, string const & n, sigc::slot<framecnt_t> g, sigc::slot<bool, framecnt_t> s) : Option (i, n) - , _clock (X_("timecode-offset"), false, X_("TimecodeOffsetClock"), true, false, true, false) + , _clock (X_("timecode-offset"), false, X_(""), true, false, true, false) , _get (g) , _set (s) { diff --git a/gtk2_ardour/patch_change_dialog.cc b/gtk2_ardour/patch_change_dialog.cc index 475ae1f6a4..4bedf63df6 100644 --- a/gtk2_ardour/patch_change_dialog.cc +++ b/gtk2_ardour/patch_change_dialog.cc @@ -35,7 +35,7 @@ PatchChangeDialog::PatchChangeDialog ( ) : ArdourDialog (_("Patch Change"), true) , _time_converter (tc) - , _time (X_("patchchangetime"), true, X_("PatchChangeTimeClock"), true, false) + , _time (X_("patchchangetime"), true, "", true, false) , _channel (*manage (new Adjustment (1, 1, 16, 1, 4))) , _program (*manage (new Adjustment (1, 1, 128, 1, 16))) , _bank (*manage (new Adjustment (1, 1, 16384, 1, 64))) diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/region_editor.cc index b80698e6ed..8a4a8b9d1e 100755 --- a/gtk2_ardour/region_editor.cc +++ b/gtk2_ardour/region_editor.cc @@ -51,13 +51,13 @@ RegionEditor::RegionEditor (Session* s, boost::shared_ptr<Region> r) , name_label (_("Name:")) , audition_button (_("Play")) , _clock_group (new ClockGroup) - , position_clock (X_("regionposition"), true, X_("RegionEditorClock"), true, false) - , end_clock (X_("regionend"), true, X_("RegionEditorClock"), true, false) - , length_clock (X_("regionlength"), true, X_("RegionEditorClock"), true, false, true) - , sync_offset_relative_clock (X_("regionsyncoffsetrelative"), true, X_("RegionEditorClock"), true, false) - , sync_offset_absolute_clock (X_("regionsyncoffsetabsolute"), true, X_("RegionEditorClock"), true, false) + , position_clock (X_("regionposition"), true, "", true, false) + , end_clock (X_("regionend"), true, "", true, false) + , length_clock (X_("regionlength"), true, "", true, false, true) + , sync_offset_relative_clock (X_("regionsyncoffsetrelative"), true, "", true, false) + , sync_offset_absolute_clock (X_("regionsyncoffsetabsolute"), true, "", true, false) /* XXX cannot file start yet */ - , start_clock (X_("regionstart"), true, X_("RegionEditorClock"), false, false) + , start_clock (X_("regionstart"), true, "", false, false) , _sources (1) { set_session (s); diff --git a/gtk2_ardour/region_layering_order_editor.cc b/gtk2_ardour/region_layering_order_editor.cc index 41528fead6..de97e0a190 100644 --- a/gtk2_ardour/region_layering_order_editor.cc +++ b/gtk2_ardour/region_layering_order_editor.cc @@ -23,7 +23,7 @@ RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor& pe) , layering_order_columns () , layering_order_model (Gtk::ListStore::create (layering_order_columns)) , layering_order_display () - , clock ("layer dialog", true, "RegionLayeringOrderEditorClock", false, false, false) + , clock ("layer dialog", true, "clock", false, false, false) , scroller () , editor (pe) { diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index f53cb87849..f18831b404 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -118,8 +118,8 @@ importmode2string (ImportMode mode) SoundFileBox::SoundFileBox (bool persistent) : table (6, 2), - length_clock ("sfboxLengthClock", !persistent, "EditCursorClock", false, false, true, false), - timecode_clock ("sfboxTimecodeClock", !persistent, "EditCursorClock", false, false, false, false), + length_clock ("sfboxLengthClock", !persistent, "", false, false, true, false), + timecode_clock ("sfboxTimecodeClock", !persistent, "", false, false, false, false), main_box (false, 6), autoplay_btn (_("Auto-play")) diff --git a/gtk2_ardour/strip_silence_dialog.cc b/gtk2_ardour/strip_silence_dialog.cc index 78e1d5cfbd..6a6c6fc0d7 100644 --- a/gtk2_ardour/strip_silence_dialog.cc +++ b/gtk2_ardour/strip_silence_dialog.cc @@ -49,8 +49,8 @@ using namespace ArdourCanvas; StripSilenceDialog::StripSilenceDialog (Session* s, list<RegionView*> const & v) : ArdourDialog (_("Strip Silence")) , ProgressReporter () - , _minimum_length (new AudioClock (X_("silence duration"), true, "SilenceDurationClock", true, false, true, false)) - , _fade_length (new AudioClock (X_("silence duration"), true, "SilenceDurationClock", true, false, true, false)) + , _minimum_length (new AudioClock (X_("silence duration"), true, "", true, false, true, false)) + , _fade_length (new AudioClock (X_("silence duration"), true, "", true, false, true, false)) , _peaks_ready_connection (0) , _destroying (false) { diff --git a/gtk2_ardour/time_info_box.cc b/gtk2_ardour/time_info_box.cc index a34314c3cd..cde7e97e51 100644 --- a/gtk2_ardour/time_info_box.cc +++ b/gtk2_ardour/time_info_box.cc @@ -46,27 +46,18 @@ TimeInfoBox::TimeInfoBox () , syncing_selection (false) , syncing_punch (false) { - 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); + selection_start = new AudioClock ("selection-start", false, "selection", false, false, false, false); + selection_end = new AudioClock ("selection-end", false, "selection", false, false, false, false); + selection_length = new AudioClock ("selection-length", false, "selection", 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); + punch_start = new AudioClock ("punch-start", false, "punch", false, false, false, false); + punch_end = new AudioClock ("punch-end", false, "punch", false, false, false, false); - CairoEditableText& ss (selection_start->main_display()); - ss.set_corner_radius (0); - - CairoEditableText& se (selection_end->main_display()); - se.set_corner_radius (0); - - CairoEditableText& sl (selection_length->main_display()); - sl.set_corner_radius (0); - - CairoEditableText& ps (punch_start->main_display()); - ps.set_corner_radius (0); - - CairoEditableText& pe (punch_end->main_display()); - pe.set_corner_radius (0); + selection_start->set_draw_background (false); + selection_end->set_draw_background (false); + selection_length->set_draw_background (false); + punch_start->set_draw_background (false); + punch_end->set_draw_background (false); selection_title.set_text (_("Selection")); punch_title.set_text (_("Punch")); @@ -88,7 +79,6 @@ TimeInfoBox::TimeInfoBox () right.set_border_width (2); right.set_col_spacings (2); - Gtk::Label* l; selection_title.set_name ("TimeInfoSelectionTitle"); diff --git a/libs/gtkmm2ext/utils.cc b/libs/gtkmm2ext/utils.cc index e8f8d69279..ff5e5d8a9c 100644 --- a/libs/gtkmm2ext/utils.cc +++ b/libs/gtkmm2ext/utils.cc @@ -391,14 +391,6 @@ Gtkmm2ext::container_clear (Gtk::Container& c) void Gtkmm2ext::rounded_rectangle (Cairo::RefPtr<Cairo::Context> context, double x, double y, double w, double h, double r) { - /* renders small shapes better than most others */ - -/* A****BQ - H C - * * - G D - F****E -*/ rounded_rectangle (context->cobj(), x, y, w, h, r); } |