X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Faudio_clock.cc;h=b64e54e95e6413d1f7120adac40de3c98ac31f59;hb=fc079a0ea3e2b8f16b8360a665d7d441fc3675a3;hp=7bbc00c2678b6c2e8ee68b7c715d9a89eabe3548;hpb=e279b9892b467aa823e253d97b6e9504cca0e252;p=ardour.git diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 7bbc00c267..b64e54e95e 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -31,6 +31,7 @@ #include "gtkmm2ext/rgb_macros.h" #include "ardour/profile.h" +#include "ardour/lmath.h" #include "ardour/session.h" #include "ardour/slave.h" #include "ardour/tempo.h" @@ -45,6 +46,7 @@ #include "i18n.h" using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtk; using namespace std; @@ -53,7 +55,7 @@ using Gtkmm2ext::Keyboard; sigc::signal AudioClock::ModeChanged; vector AudioClock::clocks; -const double AudioClock::info_font_scale_factor = 0.50; +const double AudioClock::info_font_scale_factor = 0.68; const double AudioClock::separator_height = 0.0; const double AudioClock::x_leading_padding = 6.0; @@ -63,13 +65,15 @@ const double AudioClock::x_leading_padding = 6.0; #define TXTSPAN "" AudioClock::AudioClock (const string& clock_name, bool transient, const string& widget_name, - bool allow_edit, bool follows_playhead, bool duration, bool with_info) + bool allow_edit, bool follows_playhead, bool duration, bool with_info, + bool accept_on_focus_out) : ops_menu (0) , _name (clock_name) , is_transient (transient) , is_duration (duration) , editable (allow_edit) , _follows_playhead (follows_playhead) + , _accept_on_focus_out (accept_on_focus_out) , _off (false) , em_width (0) , _edit_by_click_field (false) @@ -94,6 +98,8 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string& , last_sdelta (0) , dragging (false) , drag_field (Field (0)) + , xscale (1.0) + , yscale (1.0) { set_flags (CAN_FOCUS); @@ -152,25 +158,18 @@ AudioClock::on_realize () first_width = req.width; first_height = req.height; - set_font (); + // XXX FIX ME: define font based on ... ??? + // set_font (); set_colors (); } void -AudioClock::set_font () +AudioClock::set_font (Pango::FontDescription font) { Glib::RefPtr style = get_style (); - Pango::FontDescription font; Pango::AttrFontDesc* font_attr; - if (!is_realized()) { - font = get_font_for_style (get_name()); - } else { - font = style->get_font(); - } - font_size = font.get_size(); - font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); normal_attributes.change (*font_attr); @@ -222,15 +221,15 @@ AudioClock::set_colors () uint32_t cursor_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())); - cursor_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1 active: cursor", get_name())); + bg_color = ARDOUR_UI::config()->color (string_compose ("%1 active: background", get_name())); + text_color = ARDOUR_UI::config()->color (string_compose ("%1 active: text", get_name())); + editing_color = ARDOUR_UI::config()->color (string_compose ("%1 active: edited text", get_name())); + cursor_color = ARDOUR_UI::config()->color (string_compose ("%1 active: cursor", 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())); - cursor_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: cursor", get_name())); + bg_color = ARDOUR_UI::config()->color (string_compose ("%1: background", get_name())); + text_color = ARDOUR_UI::config()->color (string_compose ("%1: text", get_name())); + editing_color = ARDOUR_UI::config()->color (string_compose ("%1: edited text", get_name())); + cursor_color = ARDOUR_UI::config()->color (string_compose ("%1: cursor", get_name())); } /* store for bg and cursor in render() */ @@ -259,12 +258,14 @@ AudioClock::set_colors () r = lrint ((r/255.0) * 65535.0); g = lrint ((g/255.0) * 65535.0); b = lrint ((b/255.0) * 65535.0); + delete foreground_attr; 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/255.0) * 65535.0); g = lrint ((g/255.0) * 65535.0); b = lrint ((b/255.0) * 65535.0); + delete editing_attr; editing_attr = new Pango::AttrColor (Pango::Attribute::create_attr_foreground (r, g, b)); normal_attributes.change (*foreground_attr); @@ -282,7 +283,16 @@ AudioClock::set_colors () } void -AudioClock::render (cairo_t* cr) +AudioClock::set_scale (double x, double y) +{ + xscale = x; + yscale = y; + + queue_draw (); +} + +void +AudioClock::render (cairo_t* cr, cairo_rectangle_t*) { /* main layout: rounded rect, plus the text */ @@ -300,10 +310,22 @@ AudioClock::render (cairo_t* cr) cairo_fill (cr); } - cairo_move_to (cr, (get_width() - layout_width) / 2.0, (upper_height - layout_height) / 2.0); + double lw = layout_width * xscale; + double lh = layout_height * yscale; + + cairo_move_to (cr, (get_width() - lw) / 2.0, (upper_height - lh) / 2.0); + if (xscale != 1.0 || yscale != 1.0) { + cairo_save (cr); + cairo_scale (cr, xscale, yscale); + } + pango_cairo_show_layout (cr, _layout->gobj()); + if (xscale != 1.0 || yscale != 1.0) { + cairo_restore (cr); + } + if (_left_layout) { double h = get_height() - upper_height - separator_height; @@ -314,7 +336,7 @@ AudioClock::render (cairo_t* cr) if (mode_based_info_ratio != 1.0) { - double left_rect_width = round (((get_width() - separator_height) * mode_based_info_ratio) + 0.5); + double left_rect_width = get_left_rect_width(); if (_need_bg) { if (corner_radius) { @@ -450,7 +472,10 @@ AudioClock::set_clock_dimensions (Gtk::Requisition& req) tmp->set_font_description (font); /* this string is the longest thing we will ever display */ - tmp->set_text (" 88:88:88,888"); + if (_mode == MinSec) + tmp->set_text (" 88:88:88,888 "); + else + tmp->set_text (" 88:88:88,88 "); tmp->get_pixel_size (req.width, req.height); layout_height = req.height; @@ -775,31 +800,31 @@ AudioClock::parse_as_timecode_distance (const std::string& str) case 1: case 2: sscanf (str.c_str(), "%" PRId32, &frames); - return lrint ((frames/(float)fps) * sr); + return llrint ((frames/(float)fps) * sr); case 3: sscanf (str.c_str(), "%1" PRId32 "%" PRId32, &secs, &frames); - return (secs * sr) + lrint ((frames/(float)fps) * sr); + return (secs * sr) + llrint ((frames/(float)fps) * sr); case 4: sscanf (str.c_str(), "%2" PRId32 "%" PRId32, &secs, &frames); - return (secs * sr) + lrint ((frames/(float)fps) * sr); + return (secs * sr) + llrint ((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); + return (mins * 60 * sr) + (secs * sr) + llrint ((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); + return (mins * 60 * sr) + (secs * sr) + llrint ((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); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + llrint ((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); + return (hrs * 3600 * sr) + (mins * 60 * sr) + (secs * sr) + llrint ((frames/(float)fps) * sr); default: break; @@ -944,12 +969,24 @@ AudioClock::set (framepos_t when, bool force, framecnt_t offset) } if (when == last_when && !force) { +#if 0 // XXX return if no change and no change forced. verify Aug/2014 if (_mode != Timecode && _mode != MinSec) { /* may need to force display of TC source * time, so don't return early. */ + /* ^^ Why was that?, delta times? + * Timecode FPS, pull-up/down, etc changes + * trigger a 'session_property_changed' which + * eventually calls set(last_when, true) + * + * re-rendering the clock every 40ms or so just + * because we can is not ideal. + */ return; } +#else + return; +#endif } if (!editing) { @@ -1099,15 +1136,43 @@ AudioClock::set_frames (framepos_t when, bool /*force*/) } void -AudioClock::set_minsec (framepos_t when, bool /*force*/) +AudioClock::print_minsec (framepos_t when, char* buf, size_t bufsize, float frame_rate) { - char buf[32]; framecnt_t left; int hrs; int mins; int secs; int millisecs; - bool negative = false; + bool negative; + + if (when < 0) { + when = -when; + negative = true; + } else { + negative = false; + } + + left = when; + hrs = (int) floor (left / (frame_rate * 60.0f * 60.0f)); + left -= (framecnt_t) floor (hrs * frame_rate * 60.0f * 60.0f); + mins = (int) floor (left / (frame_rate * 60.0f)); + left -= (framecnt_t) floor (mins * frame_rate * 60.0f); + secs = (int) floor (left / (float) frame_rate); + left -= (framecnt_t) floor ((double)(secs * frame_rate)); + millisecs = floor (left * 1000.0 / (float) frame_rate); + + if (negative) { + snprintf (buf, bufsize, "-%02" PRId32 ":%02" PRId32 ":%02" PRId32 ".%03" PRId32, hrs, mins, secs, millisecs); + } else { + snprintf (buf, bufsize, " %02" PRId32 ":%02" PRId32 ":%02" PRId32 ".%03" PRId32, hrs, mins, secs, millisecs); + } + +} + +void +AudioClock::set_minsec (framepos_t when, bool /*force*/) +{ + char buf[32]; if (_off) { _layout->set_text (" --:--:--.---"); @@ -1120,25 +1185,7 @@ AudioClock::set_minsec (framepos_t when, bool /*force*/) return; } - if (when < 0) { - when = -when; - negative = true; - } - - left = when; - hrs = (int) floor (left / (_session->frame_rate() * 60.0f * 60.0f)); - left -= (framecnt_t) floor (hrs * _session->frame_rate() * 60.0f * 60.0f); - mins = (int) floor (left / (_session->frame_rate() * 60.0f)); - left -= (framecnt_t) floor (mins * _session->frame_rate() * 60.0f); - secs = (int) floor (left / (float) _session->frame_rate()); - left -= (framecnt_t) floor ((double)(secs * _session->frame_rate())); - millisecs = floor (left * 1000.0 / (float) _session->frame_rate()); - - if (negative) { - snprintf (buf, sizeof (buf), "-%02" PRId32 ":%02" PRId32 ":%02" PRId32 ".%03" PRId32, hrs, mins, secs, millisecs); - } else { - snprintf (buf, sizeof (buf), " %02" PRId32 ":%02" PRId32 ":%02" PRId32 ".%03" PRId32, hrs, mins, secs, millisecs); - } + print_minsec (when, buf, sizeof (buf), _session->frame_rate()); _layout->set_text (buf); set_slave_info(); @@ -1643,7 +1690,7 @@ AudioClock::on_focus_out_event (GdkEventFocus* ev) bool ret = CairoWidget::on_focus_out_event (ev); if (editing) { - end_edit (false); + end_edit (_accept_on_focus_out); } return ret; @@ -2037,6 +2084,24 @@ AudioClock::frames_from_audioframes_string (const string& str) const return f; } +void +AudioClock::copy_text_to_clipboard () const +{ + string val; + if (editing) { + val = pre_edit_string; + } else { + val = _layout->get_text (); + } + const size_t trim = val.find_first_not_of(" "); + if (trim == string::npos) { + assert(0); // empty clock, can't be right. + return; + } + Glib::RefPtr cl = Gtk::Clipboard::get(); + cl->set_text (val.substr(trim)); +} + void AudioClock::build_ops_menu () { @@ -2057,6 +2122,8 @@ AudioClock::build_ops_menu () 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))); } + ops_items.push_back (SeparatorElem()); + ops_items.push_back (MenuElem (_("Copy to clipboard"), sigc::mem_fun(*this, &AudioClock::copy_text_to_clipboard))); } void @@ -2093,6 +2160,9 @@ AudioClock::set_mode (Mode m) _layout->set_text (""); + Gtk::Requisition req; + set_clock_dimensions (req); + if (_left_layout) { _left_layout->set_attributes (info_attributes); @@ -2173,7 +2243,8 @@ AudioClock::on_style_changed (const Glib::RefPtr& old_style) Gtk::Requisition req; set_clock_dimensions (req); - set_font (); + /* XXXX fix me ... we shouldn't be using GTK styles anyway */ + // set_font (); set_colors (); }