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 | |
parent | af191fddcaabb060f67f44cc8cad0f2c3873e9fe (diff) |
break out meter&metric pattern rendering.. first step towards new mixer-meters
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/ardour3_widget_list.rc | 7 | ||||
-rw-r--r-- | gtk2_ardour/gain_meter.cc | 205 | ||||
-rw-r--r-- | gtk2_ardour/gain_meter.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/meter_patterns.cc | 469 | ||||
-rw-r--r-- | gtk2_ardour/meter_patterns.h | 38 | ||||
-rw-r--r-- | gtk2_ardour/meter_strip.cc | 463 | ||||
-rw-r--r-- | gtk2_ardour/meter_strip.h | 10 | ||||
-rw-r--r-- | gtk2_ardour/meterbridge.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/wscript | 1 |
9 files changed, 542 insertions, 666 deletions
diff --git a/gtk2_ardour/ardour3_widget_list.rc b/gtk2_ardour/ardour3_widget_list.rc index a0ce07067b..05ebde9421 100644 --- a/gtk2_ardour/ardour3_widget_list.rc +++ b/gtk2_ardour/ardour3_widget_list.rc @@ -169,12 +169,19 @@ widget "*FaderMetricsStrip" style:highest "audio_track_metrics" widget "*AudioTrackMetrics" style:highest "audio_track_metrics" widget "*MidiTrackMetrics" style:highest "midi_track_metrics" widget "*AudioBusMetrics" style:highest "audio_bus_metrics" +widget "*AudioMidiTrackMetrics" style:highest "midi_track_metrics" widget "*AudioTrackMetricsLeft" style:highest "audio_track_metrics" widget "*MidiTrackMetricsLeft" style:highest "midi_track_metrics" widget "*AudioBusMetricsLeft" style:highest "audio_bus_metrics" +widget "*AudioMidiTrackMetricsLeft" style:highest "midi_track_metrics" +widget "*AudioTrackMetricsRight" style:highest "audio_track_metrics" +widget "*MidiTrackMetricsRight" style:highest "midi_track_metrics" +widget "*AudioBusMetricsRight" style:highest "audio_bus_metrics" +widget "*AudioMidiTrackMetricsRight" style:highest "midi_track_metrics" widget "*AudioTrackMetricsInactive" style:highest "audio_track_metrics_inactive" widget "*MidiTrackMetricsInactive" style:highest "midi_track_metrics_inactive" widget "*AudioBusMetricsInactive" style:highest "audio_bus_metrics_inactive" +widget "*AudioMidiTrackMetricsInactive" style:highest "midi_track_metrics_inactive" widget "*TimeAxisViewControlsBaseUnselected" style:highest "audio_track_base" widget "*AudioTrackControlsBaseUnselected" style:highest "audio_track_base" diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index fc458cb66d..380fc56b8e 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -44,6 +44,7 @@ #include "keyboard.h" #include "public_editor.h" #include "utils.h" +#include "meter_patterns.h" #include "ardour/session.h" #include "ardour/route.h" @@ -63,14 +64,10 @@ using Gtkmm2ext::Keyboard; sigc::signal<void> GainMeterBase::ResetAllPeakDisplays; sigc::signal<void,RouteGroup*> GainMeterBase::ResetGroupPeakDisplays; -GainMeter::MetricPatterns GainMeter::metric_patterns; - GainMeterBase::GainMeterBase (Session* s, bool horizontal, int fader_length, int fader_girth) : gain_adjustment (gain_to_slider_position_with_max (1.0, Config->get_max_gain()), 0.0, 1.0, 0.01, 0.1) , gain_automation_style_button ("") , gain_automation_state_button ("") - , style_changed (false) - , dpi_changed (false) , _data_type (DataType::AUDIO) { @@ -837,9 +834,9 @@ GainMeterBase::update_meters() void GainMeterBase::color_handler(bool dpi) { - color_changed = true; - dpi_changed = (dpi) ? true : false; + meter_clear_pattern_cache(); setup_meters(); + meter_metric_area.queue_draw (); } void @@ -857,7 +854,8 @@ GainMeterBase::set_width (Width w, int len) void GainMeterBase::on_theme_changed() { - style_changed = true; + meter_clear_pattern_cache(); + meter_metric_area.queue_draw (); } GainMeter::GainMeter (Session* s, int fader_length) @@ -871,7 +869,7 @@ GainMeter::GainMeter (Session* s, int fader_length) gain_display_box.pack_start (gain_display, true, true); meter_metric_area.set_name ("AudioTrackMetrics"); - set_size_request_to_display_given_text (meter_metric_area, "-127", 1, 0); + set_size_request_to_display_given_text (meter_metric_area, "-8888", 1, 0); gain_automation_style_button.set_name ("mixer strip button"); gain_automation_state_button.set_name ("mixer strip button"); @@ -953,197 +951,10 @@ GainMeter::get_gm_width () return sz.width; } -cairo_pattern_t* -GainMeter::render_metrics (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); - Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(w.get_pango_context()); - - - Pango::AttrList audio_font_attributes; - Pango::AttrList midi_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; - - - cairo_move_to (cr, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - { - Gdk::Color c = w.get_style()->get_bg (Gtk::STATE_NORMAL); - cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p()); - } - cairo_fill (cr); - - 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()); - } - - vector<int> points; - - switch (*i) { - case DataType::AUDIO: - layout->set_attributes (audio_font_attributes); - points.push_back (-50); - points.push_back (-40); - points.push_back (-30); - points.push_back (-20); - points.push_back (-10); - points.push_back (-3); - points.push_back (0); - points.push_back (4); - break; - - case DataType::MIDI: - layout->set_attributes (midi_font_attributes); - points.push_back (0); - if (types.size() == 1) { - points.push_back (32); - } else { - /* tweak so as not to overlay the -30dB mark */ - points.push_back (48); - } - points.push_back (64); - points.push_back (96); - points.push_back (127); - break; - } - - char buf[32]; - - for (vector<int>::const_iterator j = points.begin(); j != points.end(); ++j) { - - gint pos; - - float fraction = 0; - switch (*i) { - case DataType::AUDIO: - fraction = log_meter (*j); - pos = height - (gint) floor (height * fraction); - break; - case DataType::MIDI: - fraction = *j / 127.0; - pos = 1 + height - (gint) floor (height * fraction); - break; - } - - float const linepos = min((float) height, (float)(pos + .5f)); - - cairo_set_line_width (cr, 1.0); - cairo_move_to (cr, 0, linepos); - cairo_line_to (cr, 3.5, linepos); - cairo_stroke (cr); - - snprintf (buf, sizeof (buf), "%2d", abs (*j)); - 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, 5, p); - 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 GainMeter::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() || style_changed || dpi_changed) { - 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); - - style_changed = false; - dpi_changed = false; - - cairo_destroy (cr); - - return true; + return meter_expose_metrics(ev, _types, &meter_metric_area); } boost::shared_ptr<PBD::Controllable> @@ -1206,7 +1017,7 @@ GainMeter::meter_configuration_changed (ChanCount c) } } - style_changed = true; + meter_clear_pattern_cache(); meter_metric_area.queue_draw (); } diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h index d23c9051b9..466569e355 100644 --- a/gtk2_ardour/gain_meter.h +++ b/gtk2_ardour/gain_meter.h @@ -185,9 +185,6 @@ class GainMeterBase : virtual public sigc::trackable, ARDOUR::SessionHandlePtr static sigc::signal<void,ARDOUR::RouteGroup*> ResetGroupPeakDisplays; void on_theme_changed (); - bool style_changed; - bool dpi_changed; - bool color_changed; void color_handler(bool); ARDOUR::DataType _data_type; ARDOUR::ChanCount _previous_amp_output_streams; @@ -216,10 +213,6 @@ class GainMeter : public GainMeterBase, public Gtk::VBox gint meter_metrics_expose (GdkEventExpose *); - typedef std::map<std::string,cairo_pattern_t*> MetricPatterns; - static MetricPatterns metric_patterns; - static cairo_pattern_t* render_metrics (Gtk::Widget &, std::vector<ARDOUR::DataType>); - private: void meter_configuration_changed (ARDOUR::ChanCount); diff --git a/gtk2_ardour/meter_patterns.cc b/gtk2_ardour/meter_patterns.cc new file mode 100644 index 0000000000..f7e1226b13 --- /dev/null +++ b/gtk2_ardour/meter_patterns.cc @@ -0,0 +1,469 @@ +/* + Copyright (C) 2013 Paul Davis + Author: Robin Gareus + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <gtkmm2ext/cairo_widget.h> +#include <gtkmm2ext/gtk_ui.h> +#include <gtkmm2ext/utils.h> +#include <gtkmm2ext/rgb_macros.h> + +#include "ardour_ui.h" +#include "utils.h" +#include "logmeter.h" +#include "meter_patterns.h" + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace Gtk; +using namespace Gtkmm2ext; +using namespace std; + + +static const int max_pattern_metric_size = 1026; + +cairo_pattern_t* +meter_render_ticks (Gtk::Widget& w, vector<ARDOUR::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); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + return pattern; +} + + +cairo_pattern_t* +meter_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>(-20, 1.0)); + if (types.size() == 1) { + points.insert (std::pair<int,float>(-25, 0.5)); + points.insert (std::pair<int,float>(-15, 1.0)); + } + points.insert (std::pair<int,float>(-18, 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>( 24, 0.5)); + points.insert (std::pair<int,float>( 48, 0.5)); + points.insert (std::pair<int,float>( 72, 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); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + return pattern; +} + + +typedef std::map<std::string,cairo_pattern_t*> TickPatterns; +static TickPatterns ticks_patterns; + +gint meter_expose_ticks (GdkEventExpose *ev, std::vector<ARDOUR::DataType> types, 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 = meter_render_ticks (*mta, types); + ticks_patterns[mta->get_name()] = pattern; + } 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; +} + +typedef std::map<std::string,cairo_pattern_t*> MetricPatterns; +static MetricPatterns metric_patterns; + +gint meter_expose_metrics (GdkEventExpose *ev, std::vector<ARDOUR::DataType> types, Gtk::DrawingArea *mma) +{ + Glib::RefPtr<Gdk::Window> win (mma->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 (mma->get_name()); + + if (i == metric_patterns.end()) { + pattern = meter_render_metrics (*mma, types); + metric_patterns[mma->get_name()] = pattern; + } 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; +} + +void meter_clear_pattern_cache() { + metric_patterns.clear(); + ticks_patterns.clear(); +} diff --git a/gtk2_ardour/meter_patterns.h b/gtk2_ardour/meter_patterns.h new file mode 100644 index 0000000000..5951ff2fd6 --- /dev/null +++ b/gtk2_ardour/meter_patterns.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2013 Paul Davis + Author: Robin Gareus + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_meter_patterns__ +#define __ardour_meter_patterns__ + +#include <list> +#include <vector> + +#include "ardour/types.h" +#include "gtkmm2ext/cairo_widget.h" + +cairo_pattern_t* meter_render_ticks (Gtk::Widget& w, std::vector<ARDOUR::DataType> types); +cairo_pattern_t* meter_render_metrics (Gtk::Widget& w, std::vector<ARDOUR::DataType> types); + +gint meter_expose_ticks (GdkEventExpose *ev, std::vector<ARDOUR::DataType> types, Gtk::DrawingArea *mta); +gint meter_expose_metrics (GdkEventExpose *ev, std::vector<ARDOUR::DataType> types, Gtk::DrawingArea *mma); + +void meter_clear_pattern_cache(); + +#endif + 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 diff --git a/gtk2_ardour/meter_strip.h b/gtk2_ardour/meter_strip.h index 50d41cadf2..dca86d6722 100644 --- a/gtk2_ardour/meter_strip.h +++ b/gtk2_ardour/meter_strip.h @@ -70,19 +70,9 @@ class MeterStrip : public Gtk::VBox, public RouteUI void self_delete (); gint meter_metrics_expose (GdkEventExpose *); - gint meter_ticks_expose (GdkEventExpose *, Gtk::DrawingArea *); gint meter_ticks1_expose (GdkEventExpose *); gint meter_ticks2_expose (GdkEventExpose *); - typedef std::map<std::string,cairo_pattern_t*> MetricPatterns; - static MetricPatterns metric_patterns; - - typedef std::map<std::string,cairo_pattern_t*> TickPatterns; - static TickPatterns ticks_patterns; - - static cairo_pattern_t* render_metrics (Gtk::Widget &, std::vector<ARDOUR::DataType>); - static cairo_pattern_t* render_ticks (Gtk::Widget &, std::vector<ARDOUR::DataType>); - void on_theme_changed (); void on_size_allocate (Gtk::Allocation&); diff --git a/gtk2_ardour/meterbridge.cc b/gtk2_ardour/meterbridge.cc index 9676b63ba7..71fcddd6da 100644 --- a/gtk2_ardour/meterbridge.cc +++ b/gtk2_ardour/meterbridge.cc @@ -118,8 +118,8 @@ Meterbridge::Meterbridge () , VisibilityTracker (*((Gtk::Window*) this)) , _visible (false) , _show_busses (false) - , metrics_left (2) - , metrics_right (3) + , metrics_left (1) + , metrics_right (2) , cur_max_width (-1) { set_name ("Meter Bridge"); @@ -534,9 +534,9 @@ Meterbridge::update_metrics () } } if (have_midi) { - metrics_right.set_metric_mode(3); + metrics_right.set_metric_mode(2); } else { - metrics_right.set_metric_mode(4); + metrics_right.set_metric_mode(3); } } diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 6bdbdc16a1..bb4e2035ec 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -147,6 +147,7 @@ gtk2_ardour_sources = [ 'mixer_ui.cc', 'meterbridge.cc', 'meter_strip.cc', + 'meter_patterns.cc', 'monitor_section.cc', 'mono_panner.cc', 'mono_panner_editor.cc', |