X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Faudio_clock.cc;h=23b9787408c9ea658db0556fe7d92b513461fae9;hb=d8ade6d30595a3a8be343b392e47d422940eac27;hp=28505ab46d6f06baa9770c43f37c12b7644a6549;hpb=6bcb3cde4316b17dbf9d87ac3f3c2d4430c45069;p=ardour.git diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 28505ab46d..23b9787408 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "ardour_ui.h" @@ -73,14 +74,18 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg colon4 (":"), colon5 (":"), b1 ("|"), - b2 ("|") + b2 ("|"), + last_when(0) { session = 0; last_when = 0; + last_pdelta = 0; + last_sdelta = 0; key_entry_state = 0; ops_menu = 0; dragging = false; - + bbt_reference_time = -1; + if (with_info) { frames_upper_info_label = manage (new Label); frames_lower_info_label = manage (new Label); @@ -99,6 +104,9 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0); Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0); + Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0); + Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0); + frames_info_box.pack_start (*frames_upper_info_label, true, true); frames_info_box.pack_start (*frames_lower_info_label, true, true); smpte_info_box.pack_start (*smpte_upper_info_label, true, true); @@ -335,6 +343,18 @@ AudioClock::setup_events () ms_minutes_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Minutes)); ms_seconds_ebox.signal_scroll_event().connect (bind (mem_fun(*this, &AudioClock::field_button_scroll_event), MS_Seconds)); + hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Hours)); + minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Minutes)); + seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Seconds)); + frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), SMPTE_Frames)); + audio_frames_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), AudioFrames)); + bars_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Bars)); + beats_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Beats)); + ticks_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), Ticks)); + ms_hours_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Hours)); + ms_minutes_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Minutes)); + ms_seconds_ebox.signal_key_press_event().connect (bind (mem_fun(*this, &AudioClock::field_key_press_event), MS_Seconds)); + hours_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Hours)); minutes_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Minutes)); seconds_ebox.signal_key_release_event().connect (bind (mem_fun(*this, &AudioClock::field_key_release_event), SMPTE_Seconds)); @@ -370,6 +390,15 @@ AudioClock::setup_events () ms_hours_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Hours)); ms_minutes_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Minutes)); ms_seconds_ebox.signal_focus_out_event().connect (bind (mem_fun(*this, &AudioClock::field_focus_out_event), MS_Seconds)); + + clock_base.signal_focus_in_event().connect (mem_fun (*this, &AudioClock::drop_focus_handler)); +} + +bool +AudioClock::drop_focus_handler (GdkEventFocus* ignored) +{ + Keyboard::magic_widget_drop_focus (); + return false; } void @@ -383,17 +412,40 @@ AudioClock::on_realize () } void -AudioClock::set (nframes_t when, bool force) +AudioClock::set (nframes_t when, bool force, nframes_t offset, char which) { if ((!force && !is_visible()) || session == 0) { return; } - if (when == last_when && !force) { + if (when == last_when && !offset && !force) { return; } + bool pdelta = Config->get_primary_clock_delta_edit_cursor(); + bool sdelta = Config->get_secondary_clock_delta_edit_cursor(); + + if (offset && which == 'p' && pdelta) { + when = (when > offset) ? when - offset : offset - when; + } else if (offset && which == 's' && sdelta) { + when = (when > offset) ? when - offset : offset - when; + } + + if (which == 'p' && pdelta && !last_pdelta) { + set_widget_name("TransportClockDisplayDelta"); + last_pdelta = true; + } else if (which == 'p' && !pdelta && last_pdelta) { + set_widget_name("TransportClockDisplay"); + last_pdelta = false; + } else if (which == 's' && sdelta && !last_sdelta) { + set_widget_name("SecondaryClockDisplayDelta"); + last_sdelta = true; + } else if (which == 's' && !sdelta && last_sdelta) { + set_widget_name("SecondaryClockDisplay"); + last_sdelta = false; + } + switch (_mode) { case SMPTE: set_smpte (when, force); @@ -453,15 +505,21 @@ AudioClock::set_frames (nframes_t when, bool force) sprintf (buf, "%.3fK", rate/1000.0f); } - frames_upper_info_label->set_text (buf); + if (frames_upper_info_label->get_text() != buf) { + frames_upper_info_label->set_text (buf); + } float vid_pullup = Config->get_video_pullup(); if (vid_pullup == 0.0) { - frames_lower_info_label->set_text(_("none")); + if (frames_lower_info_label->get_text () != _("none")) { + frames_lower_info_label->set_text(_("none")); + } } else { sprintf (buf, "%-6.4f", vid_pullup); - frames_lower_info_label->set_text (buf); + if (frames_lower_info_label->get_text() != buf) { + frames_lower_info_label->set_text (buf); + } } } } @@ -551,15 +609,24 @@ AudioClock::set_smpte (nframes_t when, bool force) sprintf (buf, "%.2f", smpte_frames); } - smpte_upper_info_label->set_text (buf); + if (smpte_upper_info_label->get_text() != buf) { + smpte_upper_info_label->set_text (buf); + } - if (session->smpte_drop_frames()) { - sprintf (buf, "DF"); + if ((fabs(smpte_frames - 29.97) < 0.0001) || smpte_frames == 30) { + if (session->smpte_drop_frames()) { + sprintf (buf, "DF"); + } else { + sprintf (buf, "NDF"); + } } else { - sprintf (buf, "NDF"); + // there is no drop frame alternative + buf[0] = '\0'; } - smpte_lower_info_label->set_text (buf); + if (smpte_lower_info_label->get_text() != buf) { + smpte_lower_info_label->set_text (buf); + } } } @@ -570,19 +637,47 @@ AudioClock::set_bbt (nframes_t when, bool force) BBT_Time bbt; session->tempo_map().bbt_time (when, bbt); + + /* handle a common case */ + + if (is_duration && when == 0) { + bbt.bars = 0; + bbt.beats = 0; + + } + sprintf (buf, "%03" PRIu32, bbt.bars); - bars_label.set_text (buf); + if (force || bars_label.get_text () != buf) { + bars_label.set_text (buf); + } sprintf (buf, "%02" PRIu32, bbt.beats); - beats_label.set_text (buf); + if (force || beats_label.get_text () != buf) { + beats_label.set_text (buf); + } sprintf (buf, "%04" PRIu32, bbt.ticks); - ticks_label.set_text (buf); + if (force || ticks_label.get_text () != buf) { + ticks_label.set_text (buf); + } if (bbt_upper_info_label) { - TempoMap::Metric m (session->tempo_map().metric_at (when)); + nframes64_t pos; + + if (bbt_reference_time < 0) { + pos = when; + } else { + pos = bbt_reference_time; + } + + TempoMap::Metric m (session->tempo_map().metric_at (pos)); + sprintf (buf, "%-5.2f", m.tempo().beats_per_minute()); - bbt_lower_info_label->set_text (buf); + if (bbt_lower_info_label->get_text() != buf) { + bbt_lower_info_label->set_text (buf); + } sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor()); - bbt_upper_info_label->set_text (buf); + if (bbt_upper_info_label->get_text() != buf) { + bbt_upper_info_label->set_text (buf); + } } } @@ -608,6 +703,39 @@ AudioClock::set_session (Session *s) } } +void +AudioClock::focus () +{ + switch (_mode) { + case SMPTE: + hours_ebox.grab_focus (); + break; + + case BBT: + bars_ebox.grab_focus (); + break; + + case MinSec: + ms_hours_ebox.grab_focus (); + break; + + case Frames: + frames_ebox.grab_focus (); + break; + + case Off: + break; + } +} + + +bool +AudioClock::field_key_press_event (GdkEventKey *ev, Field field) +{ + /* all key activity is handled on key release */ + return true; +} + bool AudioClock::field_key_release_event (GdkEventKey *ev, Field field) { @@ -654,7 +782,7 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field) label = &ticks_label; break; default: - return FALSE; + return false; } switch (ev->keyval) { @@ -704,22 +832,24 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field) if (_mode == MinSec && field == MS_Seconds) { new_char = '.'; } else { - return FALSE; + return false; } break; + case GDK_Tab: case GDK_Return: case GDK_KP_Enter: - case GDK_Tab: move_on = true; break; case GDK_Escape: + key_entry_state = 0; clock_base.grab_focus (); - return TRUE; + ChangeAborted(); /* EMIT SIGNAL */ + return true; default: - return FALSE; + return false; } if (!move_on) { @@ -770,11 +900,12 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field) case Bars: case Beats: case Ticks: - // Bars or beats should never be 0 - if (atoi(bars_label.get_text()) == 0) { + // Bars should never be, unless this clock is for a duration + if (atoi(bars_label.get_text()) == 0 && !is_duration) { bars_label.set_text("001"); } - if (atoi(beats_label.get_text()) == 0) { + // beats should never be 0, unless this clock is for a duration + if (atoi(beats_label.get_text()) == 0 && !is_duration) { beats_label.set_text("01"); } break; @@ -840,7 +971,14 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field) } - return TRUE; + //if user hit Enter, lose focus + switch (ev->keyval) { + case GDK_Return: + case GDK_KP_Enter: + clock_base.grab_focus (); + } + + return true; } bool @@ -848,6 +986,8 @@ AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field) { key_entry_state = 0; + Keyboard::magic_widget_grab_focus (); + switch (field) { case SMPTE_Hours: hours_ebox.set_flags (Gtk::HAS_FOCUS); @@ -897,7 +1037,7 @@ AudioClock::field_focus_in_event (GdkEventFocus *ev, Field field) break; } - return FALSE; + return false; } bool @@ -954,21 +1094,20 @@ AudioClock::field_focus_out_event (GdkEventFocus *ev, Field field) break; } - return FALSE; + Keyboard::magic_widget_drop_focus (); + + return false; } bool AudioClock::field_button_release_event (GdkEventButton *ev, Field field) { - - if (dragging) { - gdk_pointer_ungrab(GDK_CURRENT_TIME); + 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::Shift)){ - // we actually dragged so return without setting editing focus, or we shift clicked - - return TRUE; + 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 + return true; } } @@ -977,7 +1116,7 @@ AudioClock::field_button_release_event (GdkEventButton *ev, Field field) build_ops_menu (); } ops_menu->popup (1, ev->time); - return TRUE; + return true; } if (Keyboard::is_context_menu_event (ev)) { @@ -985,7 +1124,7 @@ AudioClock::field_button_release_event (GdkEventButton *ev, Field field) build_ops_menu (); } ops_menu->popup (1, ev->time); - return TRUE; + return true; } switch (ev->button) { @@ -1034,25 +1173,25 @@ AudioClock::field_button_release_event (GdkEventButton *ev, Field field) break; } - return TRUE; + return true; } bool AudioClock::field_button_press_event (GdkEventButton *ev, Field field) { - if (session == 0) return FALSE; + if (session == 0) return false; nframes_t frames = 0; switch (ev->button) { case 1: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { set (frames, true); ValueChanged (); /* EMIT_SIGNAL */ } /* make absolutely sure that the pointer is grabbed */ - gdk_pointer_grab(ev->window,FALSE , + 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; @@ -1062,7 +1201,7 @@ AudioClock::field_button_press_event (GdkEventButton *ev, Field field) break; case 2: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { set (frames, true); ValueChanged (); /* EMIT_SIGNAL */ } @@ -1070,21 +1209,23 @@ AudioClock::field_button_press_event (GdkEventButton *ev, Field field) case 3: /* used for context sensitive menu */ - return FALSE; + return false; break; default: - return FALSE; + return false; break; } - return TRUE; + return true; } bool AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) { - if (session == 0) return FALSE; + if (session == 0) { + return false; + } nframes_t frames = 0; @@ -1093,7 +1234,7 @@ AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) case GDK_SCROLL_UP: frames = get_frames (field); if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; } set (current_time() + frames, true); @@ -1104,7 +1245,7 @@ AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) case GDK_SCROLL_DOWN: frames = get_frames (field); if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; } @@ -1119,30 +1260,30 @@ AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) break; default: - return FALSE; + return false; break; } - return TRUE; + return true; } bool AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) { if (session == 0 || !dragging) { - return FALSE; + return false; } float pixel_frame_scale_factor = 0.2f; /* - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { pixel_frame_scale_factor = 0.1f; } if (Keyboard::modifier_state_contains (ev->state, - Keyboard::Control|Keyboard::Alt)) { + Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) { pixel_frame_scale_factor = 0.025f; } @@ -1177,7 +1318,7 @@ AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) } - return TRUE; + return true; } nframes_t @@ -1793,18 +1934,14 @@ AudioClock::build_ops_menu () ops_menu = new Menu; MenuList& ops_items = ops_menu->items(); ops_menu->set_name ("ArdourContextMenu"); - - Menu *mode_menu = manage (new Menu); - MenuList& mode_items = mode_menu->items(); - mode_menu->set_name ("ArdourContextMenu"); - mode_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); - mode_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT))); - mode_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec))); - mode_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); - mode_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off))); - - ops_items.push_back (MenuElem (_("Mode"), *mode_menu)); + if (!Profile->get_sae()) { + ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); + } + ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT))); + ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec))); + ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); + ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off))); } void @@ -1822,16 +1959,8 @@ AudioClock::set_mode (Mode m) if (_mode == m) { return; } - switch (_mode) { - case SMPTE: - case BBT: - case MinSec: - case Frames: - clock_base.remove (); - break; - case Off: - break; - } + + clock_base.remove (); _mode = m; @@ -1853,6 +1982,7 @@ AudioClock::set_mode (Mode m) break; case Off: + clock_base.add (off_hbox); break; } @@ -1897,7 +2027,14 @@ AudioClock::set_size_requests () break; case Off: + Gtkmm2ext::set_size_request_to_display_given_text (off_hbox, "00000", 5, 5); break; } } + +void +AudioClock::set_bbt_reference (nframes64_t pos) +{ + bbt_reference_time = pos; +}