summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-11-18 05:04:18 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-11-18 05:04:18 +0000
commit329a54d129ef436a7b7c0e82bf068719ce44cc45 (patch)
tree0bfd5b53424ebe4f50fd2fb625f05ea5f932047c /gtk2_ardour
parent30c62b5f130dff784258ba33e59eecd6da7d60c2 (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.cc237
-rw-r--r--gtk2_ardour/audio_clock.h21
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;
};