Separate DSP load indicator into generic gauge widget
authorRobin Gareus <robin@gareus.org>
Sun, 14 Jan 2018 16:38:49 +0000 (17:38 +0100)
committerRobin Gareus <robin@gareus.org>
Sun, 14 Jan 2018 17:49:22 +0000 (18:49 +0100)
gtk2_ardour/ardour_gauge.cc [new file with mode: 0644]
gtk2_ardour/ardour_gauge.h [new file with mode: 0644]
gtk2_ardour/dsp_load_indicator.cc
gtk2_ardour/dsp_load_indicator.h
gtk2_ardour/wscript

diff --git a/gtk2_ardour/ardour_gauge.cc b/gtk2_ardour/ardour_gauge.cc
new file mode 100644 (file)
index 0000000..db97286
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "gtkmm2ext/utils.h"
+#include "widgets/tooltips.h"
+
+#include "ardour_gauge.h"
+#include "ui_config.h"
+
+#define PADDING 3
+
+ArdourGauge::ArdourGauge (std::string const& max_text)
+{
+       _layout = Pango::Layout::create (get_pango_context ());
+       _layout->set_text (max_text);
+}
+
+ArdourGauge::~ArdourGauge ()
+{
+}
+
+void
+ArdourGauge::on_size_request (Gtk::Requisition* req)
+{
+       req->width = req->height = 0;
+       CairoWidget::on_size_request (req);
+
+       int w, h;
+       _layout->get_pixel_size (w, h);
+
+       req->width = std::max (req->width, std::max (12, h + PADDING));
+       req->height = std::max (req->height, 20 /*std::max (20, w + PADDING) */);
+}
+
+void
+ArdourGauge::update ()
+{
+       queue_draw ();
+       ArdourWidgets::set_tooltip (*this, tooltip_text ());
+}
+
+void
+ArdourGauge::update (std::string const& txt)
+{
+       _layout->set_text (txt);
+       update ();
+}
+
+void
+ArdourGauge::render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t*)
+{
+       cairo_t* cr = ctx->cobj ();
+       Gtkmm2ext::Color base = UIConfiguration::instance ().color ("ruler base");
+       Gtkmm2ext::Color text = UIConfiguration::instance ().color ("ruler text");
+
+       const int width = get_width ();
+       const int height = get_height ();
+
+       Gtkmm2ext::rounded_rectangle (cr, 0, 0, width, height, PADDING + 1);
+       Gtkmm2ext::set_source_rgba (cr, base);
+       cairo_fill (cr);
+
+       if (alert ()) {
+               Gtkmm2ext::rounded_rectangle (cr, 1, 1, width - 2, height - 2, PADDING + 1);
+               cairo_set_source_rgba (cr, 0.5, 0, 0, 1.0);
+               cairo_fill (cr);
+       }
+
+       Gtkmm2ext::rounded_rectangle (cr, PADDING, PADDING, width - PADDING - PADDING, height - PADDING - PADDING, PADDING + 1);
+       cairo_clip (cr);
+
+       const float lvl = level ();
+
+       int bh = (height - PADDING - PADDING) * lvl;
+       cairo_rectangle (cr, PADDING, height - PADDING - bh, width - PADDING, bh);
+
+       switch (indicator ()) {
+               case Level_OK:
+                       cairo_set_source_rgba (cr, 0, .5, 0, 1.0);
+                       break;
+               case Level_WARN:
+                       cairo_set_source_rgba (cr, .7, .6, 0, 1.0);
+                       break;
+               case Level_CRIT:
+                       cairo_set_source_rgba (cr, .9, 0, 0, 1.0);
+                       break;
+       }
+       cairo_fill (cr);
+
+       int w, h;
+       _layout->get_pixel_size (w, h);
+
+       cairo_save (cr);
+       cairo_new_path (cr);
+       cairo_translate (cr, width * .5, height * .5);
+       cairo_rotate (cr, M_PI * -.5);
+
+       cairo_move_to (cr, w * -.5, h * -.5);
+       pango_cairo_update_layout (cr, _layout->gobj());
+       Gtkmm2ext::set_source_rgb_a (cr, base, 0.5);
+       pango_cairo_layout_path (cr, _layout->gobj());
+       cairo_set_line_width (cr, 1.5);
+       cairo_stroke (cr);
+
+       cairo_move_to (cr, w * -.5, h * -.5);
+       pango_cairo_update_layout (cr, _layout->gobj());
+       Gtkmm2ext::set_source_rgba (cr, text);
+       pango_cairo_show_layout (cr, _layout->gobj());
+
+       cairo_restore (cr);
+}
diff --git a/gtk2_ardour/ardour_gauge.h b/gtk2_ardour/ardour_gauge.h
new file mode 100644 (file)
index 0000000..7f707d3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __gtkardour_gauge_h__
+#define __gtkardour_gauge_h__
+
+#include <pangomm.h>
+
+#include "gtkmm2ext/cairo_widget.h"
+
+class ArdourGauge : public CairoWidget
+{
+public:
+       ArdourGauge (std::string const& max_text = "00.0%");
+       virtual ~ArdourGauge ();
+
+protected:
+
+       enum Status {
+               Level_OK,   /* green */
+               Level_WARN, /* yellow */
+               Level_CRIT  /* red */
+       };
+
+       /* gauge's background, indicate alarming conditions eg. xrun */
+       virtual bool alert () const { return false; }
+       /* guage inidicator color */
+       virtual Status indicator () const = 0;
+       /* gauge level 0 <= level <= 1 */
+       virtual float level () const = 0;
+
+       virtual std::string tooltip_text () = 0;
+
+       void update ();
+       void update (std::string const &);
+
+private:
+       void on_size_request (Gtk::Requisition*);
+       void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
+
+       Glib::RefPtr<Pango::Layout> _layout;
+};
+
+#endif
index bf033b7b32c11efe742f9f53fc103d9e9c805e2d..f5b5afdadb3de27b17a3b72b9f262ac5871af0cb 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-#include "gtkmm2ext/utils.h"
-#include "widgets/tooltips.h"
-
 #include "ardour_ui.h"
 #include "dsp_load_indicator.h"
-#include "ui_config.h"
 
 #include "pbd/i18n.h"
 
 #define PADDING 3
 
 DspLoadIndicator::DspLoadIndicator ()
-       : _dsp_load (0)
+       : ArdourGauge ("00.0%")
+       , _dsp_load (0)
        , _xrun_count (0)
-{
-       _layout = Pango::Layout::create (get_pango_context ());
-       _layout->set_text ("99.9%");
-}
-
-DspLoadIndicator::~DspLoadIndicator ()
 {
 }
 
-void
-DspLoadIndicator::on_size_request (Gtk::Requisition* req)
-{
-       req->width = req->height = 0;
-       CairoWidget::on_size_request (req);
-
-       int w, h;
-       _layout->get_pixel_size (w, h);
-
-       req->width = std::max (req->width, std::max (12, h + PADDING));
-       req->height = std::max (req->height, 20 /*std::max (20, w + PADDING) */);
-}
-
 void
 DspLoadIndicator::set_xrun_count (const unsigned int xruns)
 {
@@ -59,8 +37,7 @@ DspLoadIndicator::set_xrun_count (const unsigned int xruns)
                return;
        }
        _xrun_count = xruns;
-       queue_draw ();
-       update_tooltip ();
+       update ();
 }
 
 void
@@ -73,82 +50,44 @@ DspLoadIndicator::set_dsp_load (const double load)
 
        char buf[64];
        snprintf (buf, sizeof (buf), "%.1f%%", _dsp_load);
-       _layout->set_text (buf);
+       update (std::string (buf));
+}
 
-       queue_draw ();
-       update_tooltip ();
+float
+DspLoadIndicator::level () const {
+       return _dsp_load / 100.f;
 }
 
-void
-DspLoadIndicator::update_tooltip ()
+bool
+DspLoadIndicator::alert () const
 {
-       char buf[64];
-       if (_xrun_count == UINT_MAX) {
-               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: ?"), _dsp_load);
-       } else if (_xrun_count > 9999) {
-               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: >10k"), _dsp_load);
-       } else {
-               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: %u"), _dsp_load, _xrun_count);
-       }
-       ArdourWidgets::set_tooltip (*this, buf);
+       return _xrun_count > 0;
 }
 
-void
-DspLoadIndicator::render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t*)
+ArdourGauge::Status
+DspLoadIndicator::indicator () const
 {
-       cairo_t* cr = ctx->cobj ();
-       Gtkmm2ext::Color base = UIConfiguration::instance ().color ("ruler base");
-       Gtkmm2ext::Color text = UIConfiguration::instance ().color ("ruler text");
-
-       const int width = get_width ();
-       const int height = get_height ();
-
-       Gtkmm2ext::rounded_rectangle (cr, 0, 0, width, height, PADDING + 1);
-       Gtkmm2ext::set_source_rgba (cr, base);
-       cairo_fill (cr);
-
-       if (_xrun_count > 0) {
-               Gtkmm2ext::rounded_rectangle (cr, 1, 1, width - 2, height - 2, PADDING + 1);
-               cairo_set_source_rgba (cr, 0.5, 0, 0, 1.0);
-               cairo_fill (cr);
-       }
-
-       Gtkmm2ext::rounded_rectangle (cr, PADDING, PADDING, width - PADDING - PADDING, height - PADDING - PADDING, PADDING + 1);
-       cairo_clip (cr);
-
-       int bh = (height - PADDING - PADDING) * _dsp_load / 100.f;
-       cairo_rectangle (cr, PADDING, height - PADDING - bh, width - PADDING, bh);
-
        if (_dsp_load > 90) {
-               cairo_set_source_rgba (cr, .9, 0, 0, 1.0);
+               return ArdourGauge::Level_OK;
        } else if (_dsp_load > 80) {
-               cairo_set_source_rgba (cr, .7, .6, 0, 1.0);
+               return ArdourGauge::Level_WARN;
        } else {
-               cairo_set_source_rgba (cr, 0, .5, 0, 1.0);
+               return ArdourGauge::Level_CRIT;
        }
-       cairo_fill (cr);
-
-       int w, h;
-       _layout->get_pixel_size (w, h);
-
-       cairo_save (cr);
-       cairo_new_path (cr);
-       cairo_translate (cr, width * .5, height * .5);
-       cairo_rotate (cr, M_PI * -.5);
-
-       cairo_move_to (cr, w * -.5, h * -.5);
-       pango_cairo_update_layout (cr, _layout->gobj());
-       Gtkmm2ext::set_source_rgb_a (cr, base, 0.5);
-       pango_cairo_layout_path (cr, _layout->gobj());
-       cairo_set_line_width (cr, 1.5);
-       cairo_stroke (cr);
-
-       cairo_move_to (cr, w * -.5, h * -.5);
-       pango_cairo_update_layout (cr, _layout->gobj());
-       Gtkmm2ext::set_source_rgba (cr, text);
-       pango_cairo_show_layout (cr, _layout->gobj());
+}
 
-       cairo_restore (cr);
+std::string
+DspLoadIndicator::tooltip_text ()
+{
+       char buf[64];
+       if (_xrun_count == UINT_MAX) {
+               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: ?"), _dsp_load);
+       } else if (_xrun_count > 9999) {
+               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: >10k"), _dsp_load);
+       } else {
+               snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: %u"), _dsp_load, _xrun_count);
+       }
+       return buf;
 }
 
 bool
index 012347e1a904c5fb744ad1dc67f997a71e34a062..bbdc4001508086394dcd204be9b97966dc808b2f 100644 (file)
 
 #include <pangomm.h>
 
-#include "gtkmm2ext/cairo_widget.h"
+#include "ardour_gauge.h"
 
-class DspLoadIndicator : public CairoWidget
+class DspLoadIndicator : public ArdourGauge
 {
-       public:
+public:
        DspLoadIndicator ();
-       ~DspLoadIndicator ();
 
        void set_xrun_count (const unsigned int xruns);
        void set_dsp_load (const double load);
 
+protected:
+       bool alert () const;
+       ArdourGauge::Status indicator () const;
+       float level () const;
+       std::string tooltip_text ();
+
 private:
-       void on_size_request (Gtk::Requisition*);
-       void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
        bool on_button_release_event (GdkEventButton*);
 
-       void update_tooltip ();
-
-       Glib::RefPtr<Pango::Layout> _layout;
        float _dsp_load;
        unsigned int _xrun_count;
 };
index c8af5ce97f1a353cba24066fa64228f99274d947..7e08f205857816c7a898262169e51e1628ac610d 100644 (file)
@@ -32,6 +32,7 @@ gtk2_ardour_sources = [
         'ambiguous_file_dialog.cc',
         'analysis_window.cc',
         'ardour_dialog.cc',
+        'ardour_gauge.cc',
         'ardour_http.cc',
         'ardour_ui.cc',
         'ardour_ui2.cc',