diff options
author | Robin Gareus <robin@gareus.org> | 2013-07-05 13:58:14 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2013-07-10 15:27:10 +0200 |
commit | 68762b9efdb2f289691586e817835c70251fc1b3 (patch) | |
tree | 8c0c282664f088bbe89e99cca9667f188f32fc2c /gtk2_ardour/meter_strip.cc | |
parent | af191fddcaabb060f67f44cc8cad0f2c3873e9fe (diff) |
break out meter&metric pattern rendering.. first step towards new mixer-meters
Diffstat (limited to 'gtk2_ardour/meter_strip.cc')
-rw-r--r-- | gtk2_ardour/meter_strip.cc | 463 |
1 files changed, 15 insertions, 448 deletions
diff --git a/gtk2_ardour/meter_strip.cc b/gtk2_ardour/meter_strip.cc index 1741e09696..9580aaf24f 100644 --- a/gtk2_ardour/meter_strip.cc +++ b/gtk2_ardour/meter_strip.cc @@ -43,6 +43,7 @@ #include "meterbridge.h" #include "meter_strip.h" +#include "meter_patterns.h" #include "i18n.h" @@ -58,10 +59,6 @@ PBD::Signal1<void,RouteGroup*> MeterStrip::ResetGroupPeakDisplays; PBD::Signal0<void> MeterStrip::MetricChanged; -MeterStrip::MetricPatterns MeterStrip::metric_patterns; -MeterStrip::TickPatterns MeterStrip::ticks_patterns; -int MeterStrip::max_pattern_metric_size = 1026; // +2 border - MeterStrip::MeterStrip (int metricmode) : AxisView(0) , RouteUI(0) @@ -250,8 +247,7 @@ MeterStrip::fast_update () void MeterStrip::on_theme_changed() { - metric_patterns.clear(); - ticks_patterns.clear(); + meter_clear_pattern_cache(); if (level_meter && _route) { int meter_width = 6; @@ -309,16 +305,14 @@ MeterStrip::meter_configuration_changed (ChanCount c) void MeterStrip::on_size_request (Gtk::Requisition* r) { - metric_patterns.clear(); - ticks_patterns.clear(); + meter_clear_pattern_cache(); VBox::on_size_request(r); } void MeterStrip::on_size_allocate (Gtk::Allocation& a) { - metric_patterns.clear(); - ticks_patterns.clear(); + meter_clear_pattern_cache(); const int wh = a.get_height(); int nh = ceilf(wh * .11f); if (nh < 52) nh = 52; @@ -331,250 +325,10 @@ MeterStrip::on_size_allocate (Gtk::Allocation& a) VBox::on_size_allocate(a); } -cairo_pattern_t* -MeterStrip::render_metrics (Gtk::Widget& w, vector<DataType> types) -{ - Glib::RefPtr<Gdk::Window> win (w.get_window()); - - bool tickleft = true; - gint width, height; - win->get_size (width, height); - - tickleft = w.get_name().substr(w.get_name().length() - 4) == "Left"; - - cairo_surface_t* surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); - cairo_t* cr = cairo_create (surface); - Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(w.get_pango_context()); - - Pango::AttrList audio_font_attributes; - Pango::AttrList midi_font_attributes; - Pango::AttrList unit_font_attributes; - - Pango::AttrFontDesc* font_attr; - Pango::FontDescription font; - - font = Pango::FontDescription (""); // use defaults - //font = get_font_for_style("gain-fader"); - //font = w.get_style()->get_font(); - - font.set_weight (Pango::WEIGHT_NORMAL); - font.set_size (9.0 * PANGO_SCALE); - font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); - audio_font_attributes.change (*font_attr); - delete font_attr; - - font.set_weight (Pango::WEIGHT_ULTRALIGHT); - font.set_stretch (Pango::STRETCH_ULTRA_CONDENSED); - font.set_size (7.5 * PANGO_SCALE); - font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); - midi_font_attributes.change (*font_attr); - delete font_attr; - - font.set_size (7.0 * PANGO_SCALE); - font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); - unit_font_attributes.change (*font_attr); - delete font_attr; - - cairo_move_to (cr, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - { - Gdk::Color c = w.get_style()->get_bg (Gtk::STATE_ACTIVE); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - cairo_fill (cr); - - height = min(max_pattern_metric_size, height); - uint32_t peakcolor = ARDOUR_UI::config()->color_by_name ("meterbridge peaklabel"); - - for (vector<DataType>::const_iterator i = types.begin(); i != types.end(); ++i) { - - Gdk::Color c; - - if (types.size() > 1) { - /* we're overlaying more than 1 set of marks, so use different colours */ - Gdk::Color c; - switch (*i) { - case DataType::AUDIO: - c = w.get_style()->get_fg (Gtk::STATE_NORMAL); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - break; - case DataType::MIDI: - c = w.get_style()->get_fg (Gtk::STATE_ACTIVE); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - break; - } - } else { - c = w.get_style()->get_fg (Gtk::STATE_NORMAL); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - - std::map<int,float> points; - - switch (*i) { - case DataType::AUDIO: - layout->set_attributes (audio_font_attributes); - points.insert (std::pair<int,float>(-50, 0.5)); - points.insert (std::pair<int,float>(-40, 0.5)); - points.insert (std::pair<int,float>(-30, 0.5)); - points.insert (std::pair<int,float>(-25, 0.5)); - points.insert (std::pair<int,float>(-20, 1.0)); - points.insert (std::pair<int,float>(-18, 1.0)); - points.insert (std::pair<int,float>(-15, 1.0)); - points.insert (std::pair<int,float>(-10, 1.0)); - points.insert (std::pair<int,float>( -5, 1.0)); - points.insert (std::pair<int,float>( -3, 0.5)); - points.insert (std::pair<int,float>( 0, 1.0)); - points.insert (std::pair<int,float>( 3, 0.5)); - break; - - case DataType::MIDI: - layout->set_attributes (midi_font_attributes); - points.insert (std::pair<int,float>( 0, 1.0)); - if (types.size() == 1) { - points.insert (std::pair<int,float>( 16, 0.5)); - points.insert (std::pair<int,float>( 32, 0.5)); - points.insert (std::pair<int,float>( 48, 0.5)); - points.insert (std::pair<int,float>( 64, 1.0)); - points.insert (std::pair<int,float>( 80, 0.5)); - points.insert (std::pair<int,float>( 96, 0.5)); - points.insert (std::pair<int,float>(100, 0.5)); - points.insert (std::pair<int,float>(112, 0.5)); - } else { - /* labels that don't overlay with dB */ - points.insert (std::pair<int,float>( 48, 0.5)); - points.insert (std::pair<int,float>( 72, 0.5)); - points.insert (std::pair<int,float>( 88, 0.5)); - } - points.insert (std::pair<int,float>(127, 1.0)); - break; - } - - char buf[32]; - gint pos; - - for (std::map<int,float>::const_iterator j = points.begin(); j != points.end(); ++j) { - - float fraction = 0; - switch (*i) { - case DataType::AUDIO: - cairo_set_line_width (cr, (j->second)); - if (j->first >= 0) { - cairo_set_source_rgb (cr, - UINT_RGBA_R_FLT(peakcolor), - UINT_RGBA_G_FLT(peakcolor), - UINT_RGBA_B_FLT(peakcolor)); - } - fraction = log_meter (j->first); - snprintf (buf, sizeof (buf), "%+2d", j->first); - pos = height - (gint) floor (height * fraction); - if (tickleft) { - cairo_move_to(cr, width-2.5, pos + .5); - cairo_line_to(cr, width, pos + .5); - } else { - cairo_move_to(cr, 0, pos + .5); - cairo_line_to(cr, 2.5, pos + .5); - } - cairo_stroke (cr); - break; - case DataType::MIDI: - cairo_set_line_width (cr, 1.0); - fraction = (j->first) / 127.0; - snprintf (buf, sizeof (buf), "%3d", j->first); - pos = 1 + height - (gint) rintf (height * fraction); - pos = min (pos, height); - if (tickleft) { - cairo_arc(cr, width - 2.0, pos + .5, 1.0, 0, 2 * M_PI); - } else { - cairo_arc(cr, 3, pos + .5, 1.0, 0, 2 * M_PI); - } - cairo_fill(cr); - break; - } - - layout->set_text(buf); - - /* we want logical extents, not ink extents here */ - - int tw, th; - layout->get_pixel_size(tw, th); - - int p = pos - (th / 2); - p = min (p, height - th); - p = max (p, 0); - - cairo_move_to (cr, width-4-tw, p); - pango_cairo_show_layout (cr, layout->gobj()); - } - } - - if (types.size() == 1) { - int tw, th; - layout->set_attributes (unit_font_attributes); - switch (types.at(0)) { - case DataType::AUDIO: - layout->set_text("dBFS"); - layout->get_pixel_size(tw, th); - break; - case DataType::MIDI: - layout->set_text("vel"); - layout->get_pixel_size(tw, th); - break; - } - Gdk::Color c = w.get_style()->get_fg (Gtk::STATE_ACTIVE); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - cairo_move_to (cr, 1, height - th - 1.5); - pango_cairo_show_layout (cr, layout->gobj()); - } - - cairo_pattern_t* pattern = cairo_pattern_create_for_surface (surface); - MetricPatterns::iterator p; - - if ((p = metric_patterns.find (w.get_name())) != metric_patterns.end()) { - cairo_pattern_destroy (p->second); - } - - metric_patterns[w.get_name()] = pattern; - - cairo_destroy (cr); - cairo_surface_destroy (surface); - - return pattern; -} - gint MeterStrip::meter_metrics_expose (GdkEventExpose *ev) { - Glib::RefPtr<Gdk::Window> win (meter_metric_area.get_window()); - cairo_t* cr; - - cr = gdk_cairo_create (win->gobj()); - - /* clip to expose area */ - - gdk_cairo_rectangle (cr, &ev->area); - cairo_clip (cr); - - cairo_pattern_t* pattern; - MetricPatterns::iterator i = metric_patterns.find (meter_metric_area.get_name()); - - if (i == metric_patterns.end()) { - pattern = render_metrics (meter_metric_area, _types); - } else { - pattern = i->second; - } - - cairo_move_to (cr, 0, 0); - cairo_set_source (cr, pattern); - - gint width, height; - win->get_size (width, height); - - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - cairo_destroy (cr); - - return true; + return meter_expose_metrics(ev, _types, &meter_metric_area); } void @@ -582,225 +336,38 @@ MeterStrip::set_metric_mode (int metricmode) { _types.clear (); switch(metricmode) { - case 1: - meter_metric_area.set_name ("AudioBusMetrics"); - _types.push_back (DataType::AUDIO); + case 0: + meter_metric_area.set_name ("MidiTrackMetricsLeft"); + _types.push_back (DataType::MIDI); break; - case 2: + case 1: meter_metric_area.set_name ("AudioTrackMetricsLeft"); _types.push_back (DataType::AUDIO); break; - case 3: - meter_metric_area.set_name ("MidiTrackMetrics"); + case 2: + meter_metric_area.set_name ("MidiTrackMetricsRight"); _types.push_back (DataType::MIDI); break; - case 4: - meter_metric_area.set_name ("AudioTrackMetrics"); - _types.push_back (DataType::AUDIO); - break; + case 3: default: - meter_metric_area.set_name ("AudioMidiTrackMetrics"); + meter_metric_area.set_name ("AudioTrackMetricsRight"); _types.push_back (DataType::AUDIO); - _types.push_back (DataType::MIDI); break; } meter_metric_area.queue_draw (); } -cairo_pattern_t* -MeterStrip::render_ticks (Gtk::Widget& w, vector<DataType> types) -{ - Glib::RefPtr<Gdk::Window> win (w.get_window()); - - gint width, height; - win->get_size (width, height); - - cairo_surface_t* surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); - cairo_t* cr = cairo_create (surface); - - cairo_move_to (cr, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - { - Gdk::Color c = w.get_style()->get_bg (Gtk::STATE_ACTIVE); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - cairo_fill (cr); - - height = min(max_pattern_metric_size, height); - uint32_t peakcolor = ARDOUR_UI::config()->color_by_name ("meterbridge peaklabel"); - - for (vector<DataType>::const_iterator i = types.begin(); i != types.end(); ++i) { - - Gdk::Color c; - c = w.get_style()->get_fg (Gtk::STATE_NORMAL); - - if (types.size() > 1) { - /* we're overlaying more than 1 set of marks, so use different colours */ - switch (*i) { - case DataType::AUDIO: - c = w.get_style()->get_fg (Gtk::STATE_NORMAL); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - break; - case DataType::MIDI: - c = w.get_style()->get_fg (Gtk::STATE_ACTIVE); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - break; - } - } else { - c = w.get_style()->get_fg (Gtk::STATE_NORMAL); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - - std::map<int,float> points; - - switch (*i) { - case DataType::AUDIO: - points.insert (std::pair<int,float>(-60, 0.5)); - points.insert (std::pair<int,float>(-50, 0.5)); - points.insert (std::pair<int,float>(-40, 0.5)); - points.insert (std::pair<int,float>(-30, 0.5)); - points.insert (std::pair<int,float>(-25, 0.5)); - points.insert (std::pair<int,float>(-20, 1.0)); - - points.insert (std::pair<int,float>(-19, 0.5)); - points.insert (std::pair<int,float>(-18, 1.0)); - points.insert (std::pair<int,float>(-17, 0.5)); - points.insert (std::pair<int,float>(-16, 0.5)); - points.insert (std::pair<int,float>(-15, 1.0)); - - points.insert (std::pair<int,float>(-14, 0.5)); - points.insert (std::pair<int,float>(-13, 0.5)); - points.insert (std::pair<int,float>(-12, 0.5)); - points.insert (std::pair<int,float>(-11, 0.5)); - points.insert (std::pair<int,float>(-10, 1.0)); - - points.insert (std::pair<int,float>( -9, 0.5)); - points.insert (std::pair<int,float>( -8, 0.5)); - points.insert (std::pair<int,float>( -7, 0.5)); - points.insert (std::pair<int,float>( -6, 0.5)); - points.insert (std::pair<int,float>( -5, 1.0)); - points.insert (std::pair<int,float>( -4, 0.5)); - points.insert (std::pair<int,float>( -3, 0.5)); - points.insert (std::pair<int,float>( -2, 0.5)); - points.insert (std::pair<int,float>( -1, 0.5)); - - points.insert (std::pair<int,float>( 0, 1.0)); - points.insert (std::pair<int,float>( 1, 0.5)); - points.insert (std::pair<int,float>( 2, 0.5)); - points.insert (std::pair<int,float>( 3, 0.5)); - points.insert (std::pair<int,float>( 4, 0.5)); - points.insert (std::pair<int,float>( 5, 0.5)); - break; - - case DataType::MIDI: - points.insert (std::pair<int,float>( 0, 1.0)); - points.insert (std::pair<int,float>( 16, 0.5)); - points.insert (std::pair<int,float>( 32, 0.5)); - points.insert (std::pair<int,float>( 48, 0.5)); - points.insert (std::pair<int,float>( 64, 1.0)); - points.insert (std::pair<int,float>( 80, 0.5)); - points.insert (std::pair<int,float>( 96, 0.5)); - points.insert (std::pair<int,float>(100, 1.0)); - points.insert (std::pair<int,float>(112, 0.5)); - points.insert (std::pair<int,float>(127, 1.0)); - break; - } - - for (std::map<int,float>::const_iterator j = points.begin(); j != points.end(); ++j) { - cairo_set_line_width (cr, (j->second)); - - float fraction = 0; - gint pos; - - switch (*i) { - case DataType::AUDIO: - if (j->first >= 0 || j->first == -9) { - cairo_set_source_rgb (cr, - UINT_RGBA_R_FLT(peakcolor), - UINT_RGBA_G_FLT(peakcolor), - UINT_RGBA_B_FLT(peakcolor)); - } else { - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - fraction = log_meter (j->first); - pos = height - (gint) floor (height * fraction); - cairo_move_to(cr, 0, pos + .5); - cairo_line_to(cr, 3, pos + .5); - cairo_stroke (cr); - break; - case DataType::MIDI: - fraction = (j->first) / 127.0; - pos = 1 + height - (gint) floor (height * fraction); - pos = min (pos, height); - cairo_arc(cr, 1.5, pos + .5, 1.0, 0, 2 * M_PI); - cairo_fill(cr); - break; - } - } - } - - cairo_pattern_t* pattern = cairo_pattern_create_for_surface (surface); - TickPatterns::iterator p; - - if ((p = ticks_patterns.find (w.get_name())) != metric_patterns.end()) { - cairo_pattern_destroy (p->second); - } - - ticks_patterns[w.get_name()] = pattern; - - cairo_destroy (cr); - cairo_surface_destroy (surface); - - return pattern; -} - gint MeterStrip::meter_ticks1_expose (GdkEventExpose *ev) { - return meter_ticks_expose(ev, &meter_ticks1_area); + return meter_expose_ticks(ev, _types, &meter_ticks1_area); } gint MeterStrip::meter_ticks2_expose (GdkEventExpose *ev) { - return meter_ticks_expose(ev, &meter_ticks2_area); -} - -gint -MeterStrip::meter_ticks_expose (GdkEventExpose *ev, Gtk::DrawingArea *mta) -{ - Glib::RefPtr<Gdk::Window> win (mta->get_window()); - cairo_t* cr; - - cr = gdk_cairo_create (win->gobj()); - - /* clip to expose area */ - - gdk_cairo_rectangle (cr, &ev->area); - cairo_clip (cr); - - cairo_pattern_t* pattern; - TickPatterns::iterator i = ticks_patterns.find (mta->get_name()); - - if (i == ticks_patterns.end()) { - pattern = render_ticks (*mta, _types); - } else { - pattern = i->second; - } - - cairo_move_to (cr, 0, 0); - cairo_set_source (cr, pattern); - - gint width, height; - win->get_size (width, height); - - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - cairo_destroy (cr); - - return true; + return meter_expose_ticks(ev, _types, &meter_ticks2_area); } void |