mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-17 04:06:26 +01:00
add a cursor (prototype) to audio clocks for editing, fix negative value display, and more
git-svn-id: svn://localhost/ardour2/branches/3.0@10692 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
5770f26bc9
commit
b4646bb4c0
2 changed files with 119 additions and 28 deletions
|
|
@ -279,6 +279,30 @@ AudioClock::render (cairo_t* cr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (editing) {
|
||||||
|
const double cursor_width = 16.0; /* need em width here, not 16 */
|
||||||
|
|
||||||
|
if (!insert_map.empty()) {
|
||||||
|
Pango::Rectangle cursor = _layout->get_cursor_strong_pos (insert_map[input_string.length()]);
|
||||||
|
|
||||||
|
cairo_set_source_rgba (cr, 0.9, 0.1, 0.1, 0.4);
|
||||||
|
cairo_rectangle (cr,
|
||||||
|
x_leading_padding + cursor.get_x()/PANGO_SCALE,
|
||||||
|
(upper_height - layout_height)/2.0,
|
||||||
|
cursor_width, cursor.get_height()/PANGO_SCALE);
|
||||||
|
cairo_fill (cr);
|
||||||
|
} else {
|
||||||
|
if (input_string.empty()) {
|
||||||
|
cairo_set_source_rgba (cr, 0.9, 0.1, 0.1, 0.4);
|
||||||
|
cairo_rectangle (cr,
|
||||||
|
(get_width()/2.0) - cursor_width,
|
||||||
|
(upper_height - layout_height)/2.0,
|
||||||
|
cursor_width, upper_height);
|
||||||
|
cairo_fill (cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -316,7 +340,7 @@ AudioClock::on_size_request (Gtk::Requisition* req)
|
||||||
where we printf a fractional value (XXX or should)
|
where we printf a fractional value (XXX or should)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp->set_text (" 88|88:88:88,88");
|
tmp->set_text (" 88|88:88:88,888");
|
||||||
|
|
||||||
tmp->get_pixel_size (req->width, req->height);
|
tmp->get_pixel_size (req->width, req->height);
|
||||||
|
|
||||||
|
|
@ -368,8 +392,13 @@ AudioClock::show_edit_status (int length)
|
||||||
void
|
void
|
||||||
AudioClock::start_edit ()
|
AudioClock::start_edit ()
|
||||||
{
|
{
|
||||||
edit_string = _layout->get_text ();
|
pre_edit_string = _layout->get_text ();
|
||||||
pre_edit_string = edit_string;
|
if (!insert_map.empty()) {
|
||||||
|
edit_string = pre_edit_string;
|
||||||
|
} else {
|
||||||
|
edit_string.clear ();
|
||||||
|
_layout->set_text ("");
|
||||||
|
}
|
||||||
input_string.clear ();
|
input_string.clear ();
|
||||||
editing = true;
|
editing = true;
|
||||||
|
|
||||||
|
|
@ -710,6 +739,7 @@ void
|
||||||
AudioClock::set_frames (framepos_t when, bool /*force*/)
|
AudioClock::set_frames (framepos_t when, bool /*force*/)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
bool negative = false;
|
||||||
|
|
||||||
if (_off) {
|
if (_off) {
|
||||||
_layout->set_text ("\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012");
|
_layout->set_text ("\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012\u2012");
|
||||||
|
|
@ -722,16 +752,26 @@ AudioClock::set_frames (framepos_t when, bool /*force*/)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf (buf, sizeof (buf), "%10" PRId64, when);
|
if (when < 0) {
|
||||||
|
when = -when;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
snprintf (buf, sizeof (buf), "-%10" PRId64, when);
|
||||||
|
} else {
|
||||||
|
snprintf (buf, sizeof (buf), " %10" PRId64, when);
|
||||||
|
}
|
||||||
|
|
||||||
_layout->set_text (buf);
|
_layout->set_text (buf);
|
||||||
|
|
||||||
if (_left_layout) {
|
if (_left_layout) {
|
||||||
framecnt_t rate = _session->frame_rate();
|
framecnt_t rate = _session->frame_rate();
|
||||||
|
|
||||||
if (fmod (rate, 1000.0) == 0.000) {
|
if (fmod (rate, 100.0) == 0.0) {
|
||||||
sprintf (buf, "%" PRId64 "K", rate/1000);
|
sprintf (buf, "SR %.1fkHz", rate/1000.0);
|
||||||
} else {
|
} else {
|
||||||
sprintf (buf, "%" PRId64, rate);
|
sprintf (buf, "SR %" PRId64, rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
_left_layout->set_text (buf);
|
_left_layout->set_text (buf);
|
||||||
|
|
@ -739,9 +779,9 @@ AudioClock::set_frames (framepos_t when, bool /*force*/)
|
||||||
float vid_pullup = _session->config.get_video_pullup();
|
float vid_pullup = _session->config.get_video_pullup();
|
||||||
|
|
||||||
if (vid_pullup == 0.0) {
|
if (vid_pullup == 0.0) {
|
||||||
_right_layout->set_text (_("none"));
|
_right_layout->set_text (_("pullup: \u2012"));
|
||||||
} else {
|
} else {
|
||||||
sprintf (buf, "%-6.4f", vid_pullup);
|
sprintf (buf, _("pullup %-6.4f"), vid_pullup);
|
||||||
_right_layout->set_text (buf);
|
_right_layout->set_text (buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -797,14 +837,14 @@ AudioClock::set_timecode (framepos_t when, bool force)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
Timecode::Time TC;
|
Timecode::Time TC;
|
||||||
bool negative;
|
bool negative = false;
|
||||||
|
|
||||||
if (_off) {
|
if (_off) {
|
||||||
_layout->set_text ("\u2012\u2012:\u2012\u2012:\u2012\u2012:\u2012\u2012");
|
_layout->set_text ("\u2012\u2012:\u2012\u2012:\u2012\u2012:\u2012\u2012");
|
||||||
if (_left_layout) {
|
if (_left_layout) {
|
||||||
_left_layout->set_text ("");
|
_left_layout->set_text ("");
|
||||||
_right_layout->set_text ("");
|
_right_layout->set_text ("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -846,10 +886,10 @@ AudioClock::set_bbt (framepos_t when, bool force)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[16];
|
||||||
Timecode::BBT_Time BBT;
|
Timecode::BBT_Time BBT;
|
||||||
bool negative;
|
bool negative = false;
|
||||||
|
|
||||||
if (_off) {
|
if (_off) {
|
||||||
_layout->set_text ("\u2012\u2012|\u2012\u2012|\u2012\u2012\u2012\u2012");
|
_layout->set_text ("\u2012\u2012\u2012|\u2012\u2012|\u2012\u2012\u2012\u2012");
|
||||||
if (_left_layout) {
|
if (_left_layout) {
|
||||||
_left_layout->set_text ("");
|
_left_layout->set_text ("");
|
||||||
_right_layout->set_text ("");
|
_right_layout->set_text ("");
|
||||||
|
|
@ -878,9 +918,9 @@ AudioClock::set_bbt (framepos_t when, bool force)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative) {
|
if (negative) {
|
||||||
snprintf (buf, sizeof (buf), "-%02" PRIu32 "|%02" PRIu32 "|%04" PRIu32, BBT.bars, BBT.beats, BBT.ticks);
|
snprintf (buf, sizeof (buf), "-%03" PRIu32 "|%02" PRIu32 "|%04" PRIu32, BBT.bars, BBT.beats, BBT.ticks);
|
||||||
} else {
|
} else {
|
||||||
snprintf (buf, sizeof (buf), " %02" PRIu32 "|%02" PRIu32 "|%04" PRIu32, BBT.bars, BBT.beats, BBT.ticks);
|
snprintf (buf, sizeof (buf), " %03" PRIu32 "|%02" PRIu32 "|%04" PRIu32, BBT.bars, BBT.beats, BBT.ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
_layout->set_text (buf);
|
_layout->set_text (buf);
|
||||||
|
|
@ -1061,7 +1101,7 @@ AudioClock::on_key_release_event (GdkEventKey *ev)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_string.length() >= insert_max) {
|
if (!insert_map.empty() && (input_string.length() >= insert_map.size())) {
|
||||||
/* eat the key event, but do no nothing with it */
|
/* eat the key event, but do no nothing with it */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1071,12 +1111,18 @@ AudioClock::on_key_release_event (GdkEventKey *ev)
|
||||||
string::reverse_iterator ri;
|
string::reverse_iterator ri;
|
||||||
vector<int> insert_at;
|
vector<int> insert_at;
|
||||||
int highlight_length;
|
int highlight_length;
|
||||||
|
char buf[32];
|
||||||
|
framepos_t pos;
|
||||||
|
|
||||||
/* merge with pre-edit-string into edit string */
|
/* merge with pre-edit-string into edit string */
|
||||||
|
|
||||||
switch (_mode) {
|
switch (_mode) {
|
||||||
case Frames:
|
case Frames:
|
||||||
edit_string = input_string;
|
/* get this one in the right order, and to the right width */
|
||||||
|
edit_string.push_back (new_char);
|
||||||
|
sscanf (edit_string.c_str(), "%" PRId64, &pos);
|
||||||
|
snprintf (buf, sizeof (buf), " %10" PRId64, pos);
|
||||||
|
edit_string = buf;
|
||||||
highlight_length = edit_string.length();
|
highlight_length = edit_string.length();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1511,7 +1557,10 @@ AudioClock::frames_from_timecode_string (const string& str) const
|
||||||
Timecode::Time TC;
|
Timecode::Time TC;
|
||||||
framepos_t sample;
|
framepos_t sample;
|
||||||
|
|
||||||
sscanf (str.c_str(), "%d:%d:%d:%d", &TC.hours, &TC.minutes, &TC.seconds, &TC.frames);
|
if (sscanf (str.c_str(), "%d:%d:%d:%d", &TC.hours, &TC.minutes, &TC.seconds, &TC.frames) != 4) {
|
||||||
|
error << string_compose (_("programming error: %1 %2"), "badly formatted timecode clock string", str) << endmsg;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TC.rate = _session->timecode_frames_per_second();
|
TC.rate = _session->timecode_frames_per_second();
|
||||||
TC.drop= _session->timecode_drop_frames();
|
TC.drop= _session->timecode_drop_frames();
|
||||||
|
|
@ -1533,7 +1582,11 @@ AudioClock::frames_from_minsec_string (const string& str) const
|
||||||
int hrs, mins, secs, millisecs;
|
int hrs, mins, secs, millisecs;
|
||||||
framecnt_t sr = _session->frame_rate();
|
framecnt_t sr = _session->frame_rate();
|
||||||
|
|
||||||
sscanf (str.c_str(), "%d:%d:%d:%d", &hrs, &mins, &secs, &millisecs);
|
if (sscanf (str.c_str(), "%d:%d:%d.%d", &hrs, &mins, &secs, &millisecs) != 4) {
|
||||||
|
error << string_compose (_("programming error: %1 %2"), "badly formatted minsec clock string", str) << endmsg;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (framepos_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr) + (millisecs * sr / 1000.0));
|
return (framepos_t) floor ((hrs * 60.0f * 60.0f * sr) + (mins * 60.0f * sr) + (secs * sr) + (millisecs * sr / 1000.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1635,25 +1688,56 @@ AudioClock::set_mode (Mode m)
|
||||||
|
|
||||||
_mode = m;
|
_mode = m;
|
||||||
|
|
||||||
|
insert_map.clear();
|
||||||
|
|
||||||
|
_layout->set_text ("");
|
||||||
|
|
||||||
|
if (_left_layout) {
|
||||||
|
_left_layout->set_text ("");
|
||||||
|
_right_layout->set_text ("");
|
||||||
|
}
|
||||||
|
|
||||||
switch (_mode) {
|
switch (_mode) {
|
||||||
case Timecode:
|
case Timecode:
|
||||||
insert_max = 9; // 8 digits + sign [-]2:2:2:2
|
|
||||||
mode_based_info_ratio = 0.5;
|
mode_based_info_ratio = 0.5;
|
||||||
|
insert_map.push_back (11);
|
||||||
|
insert_map.push_back (10);
|
||||||
|
insert_map.push_back (8);
|
||||||
|
insert_map.push_back (7);
|
||||||
|
insert_map.push_back (5);
|
||||||
|
insert_map.push_back (4);
|
||||||
|
insert_map.push_back (2);
|
||||||
|
insert_map.push_back (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BBT:
|
case BBT:
|
||||||
insert_max = 8; // 8 digits, 2|2|4
|
|
||||||
mode_based_info_ratio = 0.5;
|
mode_based_info_ratio = 0.5;
|
||||||
|
insert_map.push_back (11);
|
||||||
|
insert_map.push_back (10);
|
||||||
|
insert_map.push_back (9);
|
||||||
|
insert_map.push_back (8);
|
||||||
|
insert_map.push_back (6);
|
||||||
|
insert_map.push_back (5);
|
||||||
|
insert_map.push_back (3);
|
||||||
|
insert_map.push_back (2);
|
||||||
|
insert_map.push_back (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MinSec:
|
case MinSec:
|
||||||
insert_max = 9; // 7 digits 2:2:2.3
|
|
||||||
mode_based_info_ratio = 1.0;
|
mode_based_info_ratio = 1.0;
|
||||||
|
insert_map.push_back (12);
|
||||||
|
insert_map.push_back (11);
|
||||||
|
insert_map.push_back (10);
|
||||||
|
insert_map.push_back (8);
|
||||||
|
insert_map.push_back (7);
|
||||||
|
insert_map.push_back (5);
|
||||||
|
insert_map.push_back (4);
|
||||||
|
insert_map.push_back (2);
|
||||||
|
insert_map.push_back (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Frames:
|
case Frames:
|
||||||
insert_max = INT_MAX;
|
mode_based_info_ratio = 0.5;
|
||||||
mode_based_info_ratio = 1.0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,18 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
|
||||||
|
|
||||||
Field index_to_field (int index) const;
|
Field index_to_field (int index) const;
|
||||||
|
|
||||||
|
/* this maps the number of input characters/digits when editing
|
||||||
|
to a cursor position. insert_map[N] = index of character/digit
|
||||||
|
where the cursor should be after N chars/digits. it is
|
||||||
|
mode specific and so it is filled during set_mode().
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::vector<int> insert_map;
|
||||||
|
|
||||||
bool editing;
|
bool editing;
|
||||||
std::string edit_string;
|
std::string edit_string;
|
||||||
std::string pre_edit_string;
|
std::string pre_edit_string;
|
||||||
std::string input_string;
|
std::string input_string;
|
||||||
std::string::size_type insert_max;
|
|
||||||
|
|
||||||
framepos_t bbt_reference_time;
|
framepos_t bbt_reference_time;
|
||||||
framepos_t last_when;
|
framepos_t last_when;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue