diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-18 05:04:18 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-11-18 05:04:18 +0000 |
commit | 329a54d129ef436a7b7c0e82bf068719ce44cc45 (patch) | |
tree | 0bfd5b53424ebe4f50fd2fb625f05ea5f932047c /gtk2_ardour | |
parent | 30c62b5f130dff784258ba33e59eecd6da7d60c2 (diff) |
implement relative clock editing (terminated by + or - keys, which adjust the clock by the amount of time entered)
git-svn-id: svn://localhost/ardour2/branches/3.0@10670 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/audio_clock.cc | 237 | ||||
-rw-r--r-- | gtk2_ardour/audio_clock.h | 21 |
2 files changed, 170 insertions, 88 deletions
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index f3bde6187f..e1e468e544 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -75,8 +75,6 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string& , last_sdelta (0) , dragging (false) , drag_field (Field (0)) - , _canonical_time_is_displayed (true) - , _canonical_time (0) { set_flags (CAN_FOCUS); @@ -407,8 +405,36 @@ AudioClock::end_edit (bool modify) edit_string = pre_edit_string; input_string.clear (); _layout->set_text (edit_string); + show_edit_status (1); + /* edit attributes remain in use */ } else { + editing = false; + framepos_t pos; + + switch (_mode) { + case Timecode: + pos = frames_from_timecode_string (edit_string); + break; + + case BBT: + if (is_duration) { + pos = frame_duration_from_bbt_string (0, edit_string); + } else { + pos = frames_from_bbt_string (0, edit_string); + } + break; + + case MinSec: + pos = frames_from_minsec_string (edit_string); + break; + + case Frames: + pos = frames_from_audioframes_string (edit_string); + break; + } + + set (pos, true); _layout->set_attributes (normal_attributes); ValueChanged(); /* EMIT_SIGNAL */ } @@ -422,17 +448,20 @@ AudioClock::end_edit (bool modify) queue_draw (); if (!editing) { + drop_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::drop_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 (); } } @@ -451,12 +480,99 @@ AudioClock::parse_as_frames_distance (const std::string& str) framecnt_t AudioClock::parse_as_minsec_distance (const std::string& str) { + framecnt_t sr = _session->frame_rate(); + int msecs; + int secs; + int mins; + int hrs; + + switch (str.length()) { + case 0: + return 0; + case 1: + case 2: + case 3: + case 4: + sscanf (str.c_str(), "%" PRId32, &msecs); + return msecs * (sr / 1000); + + case 5: + sscanf (str.c_str(), "%1" PRId32 "%" PRId32, &secs, &msecs); + return (secs * sr) + (msecs * (sr/1000)); + + case 6: + sscanf (str.c_str(), "%2" PRId32 "%" PRId32, &secs, &msecs); + return (secs * sr) + (msecs * (sr/1000)); + + case 7: + sscanf (str.c_str(), "%1" PRId32 "%2" PRId32 "%" PRId32, &mins, &secs, &msecs); + return (mins * 60 * sr) + (secs * sr) + (msecs * (sr/1000)); + + case 8: + sscanf (str.c_str(), "%2" PRId32 "%2" PRId32 "%" PRId32, &mins, &secs, &msecs); + return (mins * 60 * sr) + (secs * sr) + (msecs * (sr/1000)); + + case 9: + sscanf (str.c_str(), "%1" PRId32 "%2" PRId32 "%2" PRId32 "%" PRId32, &hrs, &mins, &secs, &msecs); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + (msecs * (sr/1000)); + + case 10: + sscanf (str.c_str(), "%1" PRId32 "%2" PRId32 "%2" PRId32 "%" PRId32, &hrs, &mins, &secs, &msecs); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + (msecs * (sr/1000)); + + default: + break; + } + return 0; } framecnt_t AudioClock::parse_as_timecode_distance (const std::string& str) { + double fps = _session->timecode_frames_per_second(); + framecnt_t sr = _session->frame_rate(); + int frames; + int secs; + int mins; + int hrs; + + switch (str.length()) { + case 0: + return 0; + case 1: + case 2: + sscanf (str.c_str(), "%" PRId32, &frames); + return lrint ((frames/(float)fps) * sr); + + case 3: + sscanf (str.c_str(), "%1" PRId32 "%" PRId32, &secs, &frames); + return (secs * sr) + lrint ((frames/(float)fps) * sr); + + case 4: + sscanf (str.c_str(), "%2" PRId32 "%" PRId32, &secs, &frames); + return (secs * sr) + lrint ((frames/(float)fps) * sr); + + case 5: + sscanf (str.c_str(), "%1" PRId32 "%2" PRId32 "%" PRId32, &mins, &secs, &frames); + return (mins * 60 * sr) + (secs * sr) + lrint ((frames/(float)fps) * sr); + + case 6: + sscanf (str.c_str(), "%2" PRId32 "%2" PRId32 "%" PRId32, &mins, &secs, &frames); + return (mins * 60 * sr) + (secs * sr) + lrint ((frames/(float)fps) * sr); + + case 7: + sscanf (str.c_str(), "%1" PRId32 "%2" PRId32 "%2" PRId32 "%" PRId32, &hrs, &mins, &secs, &frames); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + lrint ((frames/(float)fps) * sr); + + case 8: + sscanf (str.c_str(), "%2" PRId32 "%2" PRId32 "%2" PRId32 "%" PRId32, &hrs, &mins, &secs, &frames); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + lrint ((frames/(float)fps) * sr); + + default: + break; + } + return 0; } @@ -467,8 +583,14 @@ AudioClock::parse_as_bbt_distance (const std::string& str) } framecnt_t -AudioClock::parse_as_distance (const std::string& str) +AudioClock::parse_as_distance (const std::string& instr) { + string str = instr; + + /* the input string is in reverse order */ + + std::reverse (str.begin(), str.end()); + switch (_mode) { case Timecode: return parse_as_timecode_distance (str); @@ -493,6 +615,9 @@ AudioClock::end_edit_relative (bool add) editing = false; + editing = false; + _layout->set_attributes (normal_attributes); + if (frames != 0) { if (add) { set (current_time() + frames, true); @@ -505,18 +630,12 @@ AudioClock::end_edit_relative (bool add) set (0, true); } } + ValueChanged (); /* EMIT SIGNAL */ } - /* 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 (); - } + input_string.clear (); + queue_draw (); + drop_focus (); } void @@ -602,10 +721,6 @@ AudioClock::set (framepos_t when, bool force, framecnt_t offset, char which) } last_when = when; - - /* we're setting the time from a frames value, so keep it as the canonical value */ - _canonical_time = when; - _canonical_time_is_displayed = false; } void @@ -912,11 +1027,13 @@ AudioClock::on_key_release_event (GdkEventKey *ev) case GDK_minus: case GDK_KP_Subtract: end_edit_relative (false); + return true; break; case GDK_plus: case GDK_KP_Add: end_edit_relative (true); + return true; break; case GDK_Tab: @@ -1287,30 +1404,7 @@ AudioClock::get_frame_step (Field field, framepos_t pos, int dir) framepos_t AudioClock::current_time (framepos_t pos) const { - // if (!_canonical_time_is_displayed) { - // return _canonical_time; - //} - - framepos_t ret = 0; - - switch (_mode) { - case Timecode: - ret = timecode_frame_from_display (); - break; - case BBT: - ret = bbt_frame_from_display (pos); - break; - - case MinSec: - ret = minsec_frame_from_display (); - break; - - case Frames: - ret = audio_frame_from_display (); - break; - } - - return ret; + return last_when; } framepos_t @@ -1320,18 +1414,18 @@ AudioClock::current_duration (framepos_t pos) const switch (_mode) { case Timecode: - ret = timecode_frame_from_display (); + ret = last_when; break; case BBT: - ret = bbt_frame_duration_from_display (pos); + ret = frame_duration_from_bbt_string (pos, _layout->get_text()); break; case MinSec: - ret = minsec_frame_from_display (); + ret = last_when; break; case Frames: - ret = audio_frame_from_display (); + ret = last_when; break; } @@ -1384,7 +1478,7 @@ AudioClock::timecode_validate_edit (const string& str) } framepos_t -AudioClock::timecode_frame_from_display () const +AudioClock::frames_from_timecode_string (const string& str) const { if (_session == 0) { return 0; @@ -1393,7 +1487,7 @@ AudioClock::timecode_frame_from_display () const Timecode::Time TC; framepos_t sample; - sscanf (_layout->get_text().c_str(), "%d:%d:%d:%d", &TC.hours, &TC.minutes, &TC.seconds, &TC.frames); + sscanf (str.c_str(), "%d:%d:%d:%d", &TC.hours, &TC.minutes, &TC.seconds, &TC.frames); TC.rate = _session->timecode_frames_per_second(); TC.drop= _session->timecode_drop_frames(); @@ -1406,7 +1500,7 @@ AudioClock::timecode_frame_from_display () const } framepos_t -AudioClock::minsec_frame_from_display () const +AudioClock::frames_from_minsec_string (const string& str) const { if (_session == 0) { return 0; @@ -1415,12 +1509,12 @@ AudioClock::minsec_frame_from_display () const 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); + sscanf (str.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 +AudioClock::frames_from_bbt_string (framepos_t pos, const string& str) const { if (_session == 0) { error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; @@ -1430,7 +1524,7 @@ AudioClock::bbt_frame_from_display (framepos_t pos) const AnyTime any; any.type = AnyTime::BBT; - sscanf (_layout->get_text().c_str(), "%" PRId32 "|%" PRId32 "|%" PRId32, &any.bbt.bars, &any.bbt.beats, &any.bbt.ticks); + sscanf (str.c_str(), "%" PRId32 "|%" PRId32 "|%" PRId32, &any.bbt.bars, &any.bbt.beats, &any.bbt.ticks); if (is_duration) { any.bbt.bars++; @@ -1443,7 +1537,7 @@ AudioClock::bbt_frame_from_display (framepos_t pos) const framepos_t -AudioClock::bbt_frame_duration_from_display (framepos_t pos) const +AudioClock::frame_duration_from_bbt_string (framepos_t pos, const string& str) const { if (_session == 0) { error << "AudioClock::current_time() called with BBT mode but without session!" << endmsg; @@ -1452,16 +1546,16 @@ AudioClock::bbt_frame_duration_from_display (framepos_t pos) const Timecode::BBT_Time bbt; - sscanf (_layout->get_text().c_str(), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, &bbt.bars, &bbt.beats, &bbt.ticks); + sscanf (str.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 +AudioClock::frames_from_audioframes_string (const string& str) const { framepos_t f; - sscanf (_layout->get_text().c_str(), "%" PRId64, &f); + sscanf (str.c_str(), "%" PRId64, &f); return f; } @@ -1582,16 +1676,11 @@ AudioClock::set_off (bool yn) _off = yn; - if (_off) { - _canonical_time = current_time (); - _canonical_time_is_displayed = false; - } else { - _canonical_time_is_displayed = true; - } - - /* force a possible redraw */ + /* force a redraw. last_when will be preserved, but the clock text will + * change + */ - set (_canonical_time, true); + set (last_when, true); } void diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h index 061e790735..3f3c5dc846 100644 --- a/gtk2_ardour/audio_clock.h +++ b/gtk2_ardour/audio_clock.h @@ -152,13 +152,6 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr 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, - * and _canonical_time should be returned as the `current' time of the clock. - */ - bool _canonical_time_is_displayed; - framepos_t _canonical_time; - void on_realize (); bool on_key_press_event (GdkEventKey *); bool on_key_release_event (GdkEventKey *); @@ -181,11 +174,11 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr bool timecode_validate_edit (const std::string&); bool bbt_validate_edit (const std::string&); - 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; - framepos_t minsec_frame_from_display () const; - framepos_t audio_frame_from_display () const; + framepos_t frames_from_timecode_string (const std::string&) const; + framepos_t frames_from_bbt_string (framepos_t, const std::string&) const; + framepos_t frame_duration_from_bbt_string (framepos_t, const std::string&) const; + framepos_t frames_from_minsec_string (const std::string&) const; + framepos_t frames_from_audioframes_string (const std::string&) const; void build_ops_menu (); @@ -208,8 +201,8 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr void set_colors (); void show_edit_status (int length); - void timecode_tester (); - + void drop_focus (); + double bg_r, bg_g, bg_b, bg_a; }; |