[Xfce4-commits] [panel-plugins/xfce4-hardware-monitor-plugin] 24/29: Move out CurveView text overlay and do_draw_loop implementation to CanvasView

noreply at xfce.org noreply at xfce.org
Mon Dec 18 12:45:55 CET 2017


This is an automated email from the git hooks/post-receive script.

o   m   e   g   a   p   h   i   l       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository panel-plugins/xfce4-hardware-monitor-plugin.

commit 9a268f6f317196607af28e23a55b0597bd5c7617
Author: OmegaPhil <OmegaPhil at startmail.com>
Date:   Sun Dec 17 18:19:44 2017 +0000

    Move out CurveView text overlay and do_draw_loop implementation to CanvasView
    
    This allows for more than just the CurveView to implement a text
    overlay, similarly for allowing maxima to be grouped per monitor
    types. Just CurveView uses the new template function, others will
    be next
---
 po/POTFILES.in             |   1 +
 src/bar-view.cpp           |  29 ----
 src/bar-view.hpp           |  29 +++-
 src/canvas-view.cpp        | 347 +++++++++++++++++++++++++++++++++++++++++++-
 src/canvas-view.hpp        |  46 +++++-
 src/column-view.cpp        |  28 ----
 src/column-view.hpp        |  29 +++-
 src/curve-view.cpp         | 352 ++-------------------------------------------
 src/curve-view.hpp         |  55 ++++---
 src/flame-view.cpp         |  31 ----
 src/flame-view.hpp         |  32 ++++-
 src/plugin.cpp             |  18 +--
 src/plugin.hpp             |   6 +-
 src/preferences-window.cpp |  12 +-
 14 files changed, 529 insertions(+), 486 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 16d36df..e7b05d7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,6 +2,7 @@
 # Please keep this file sorted alphabetically.
 xfce4-hardware-monitor-plugin.desktop.in
 src/bar-view.cpp
+src/canvas-view.cpp
 src/choose-monitor-window.cpp
 src/column-view.cpp
 src/curve-view.cpp
diff --git a/src/bar-view.cpp b/src/bar-view.cpp
index 78e78e8..3601fa0 100644
--- a/src/bar-view.cpp
+++ b/src/bar-view.cpp
@@ -21,40 +21,11 @@
 #include <cmath>    // for ceil/floor
 #include <algorithm>    // for max/min
 
-#include <libgnomecanvasmm/rect.h>
-
 #include "bar-view.hpp"
 #include "plugin.hpp"
 #include "monitor.hpp"
 
 
-//
-// class Bar - represents a single bar graph
-//
-
-class Bar
-{
-public:
-  Bar(Monitor *monitor, unsigned int fill_color, bool horizontal = false);
-  ~Bar();
-
-  void draw(Gnome::Canvas::Canvas &canvas,
-      Plugin *plugin, int width, int height, int no, int total,
-      double time_offset, double max);
-  double get_max_value();
-  void update();
-
-  Monitor *monitor;
-  
-private:
-  typedef std::vector<Gnome::Canvas::Rect *> box_sequence;
-  box_sequence boxes;
-
-  double old_value, new_value;
-  bool horizontal;
-  unsigned int fill_color;
-};
-
 Bar::Bar(Monitor *m, unsigned int c, bool horizontal)
   : monitor(m), old_value(0), new_value(0), fill_color(c)
 {
diff --git a/src/bar-view.hpp b/src/bar-view.hpp
index 2865df2..762935b 100644
--- a/src/bar-view.hpp
+++ b/src/bar-view.hpp
@@ -25,11 +25,38 @@
 #include <memory>
 
 #include <libgnomecanvasmm/canvas.h>
+#include <libgnomecanvasmm/rect.h>
+
 #include <glibmm/ustring.h>
 
 #include "canvas-view.hpp"
 
-class Bar;
+//
+// class Bar - represents a single bar graph
+//
+
+class Bar
+{
+public:
+  Bar(Monitor *monitor, unsigned int fill_color, bool horizontal = false);
+  ~Bar();
+
+  void draw(Gnome::Canvas::Canvas &canvas,
+      Plugin *plugin, int width, int height, int no, int total,
+      double time_offset, double max);
+  double get_max_value();
+  void update();
+
+  Monitor *monitor;
+
+private:
+  typedef std::vector<Gnome::Canvas::Rect *> box_sequence;
+  box_sequence boxes;
+
+  double old_value, new_value;
+  bool horizontal;
+  unsigned int fill_color;
+};
 
 class BarView: public CanvasView
 {
diff --git a/src/canvas-view.cpp b/src/canvas-view.cpp
index 9474732..28d4ea3 100644
--- a/src/canvas-view.cpp
+++ b/src/canvas-view.cpp
@@ -26,18 +26,29 @@
 #include "canvas-view.hpp"
 #include "plugin.hpp"
 
+#include "bar-view.hpp"
+#include "curve-view.hpp"
+#include "flame-view.hpp"
+
 
 int const CanvasView::draw_interval = 100;
 int const CanvasView::draw_iterations = 10;
 
+// Text overlay format string substitution codes
+const Glib::ustring CanvasView::monitor_full = "%M";
+const Glib::ustring CanvasView::monitor_compact = "%m";
+const Glib::ustring CanvasView::graph_max_full = "%A";
+const Glib::ustring CanvasView::graph_max_compact = "%a";
+
 CanvasView::CanvasView(bool keeps_history)
-  : View(keeps_history)
+  : View(keeps_history), text_overlay(NULL)
 {
 }
 
 CanvasView::~CanvasView()
 {
-  draw_timer.disconnect();  // FIXME: is this enough to prevent crash?
+  draw_timer.disconnect();
+  delete text_overlay;
 }
 
 void CanvasView::do_display()
@@ -141,3 +152,335 @@ bool CanvasView::draw_loop()
   return true;
 }
 
+template <typename T>
+std::list<std::pair<T*, double>> CanvasView::process_mon_maxes_text_overlay(
+    typename std::list<T*> graph_elements)
+{
+  double max;
+  typename std::list<std::pair<T*, double>> elems_and_maxes;
+
+  /* NULL references are not allowed, so those passed in must already be
+   * initialised */
+
+  // Monitor maxes maintained as a pair of <normal max>, <fixed max>
+  std::map<Glib::ustring, std::pair<int, int>> monitor_maxes;
+
+  // Monitors collected by type to allow easy access to separated data sets
+  typename std::map<Glib::ustring, std::list<T*>> elems_by_mon_type;
+
+  Glib::ustring max_formatted, max_formatted_compact, monitor_data,
+      monitor_data_compact, overlay_text, per_type_overlay_text,
+      text_overlay_format_string, tag_string,
+      separator_string = plugin->get_viewer_text_overlay_separator();
+  bool graph_max_needed = false, graph_max_compact_needed = false,
+      monitor_data_needed = false, monitor_data_compact_needed = false,
+      text_overlay_enabled = plugin->get_viewer_text_overlay_enabled();
+
+  /* Obtain maximum value of all curves/flames/bars etc in the view on a per monitor type basis
+   * but only when the user wants visualisations to be split by type,
+   * separately tracking fixed maxes incase all monitors are fixed. Graphs with
+   * fixed monitors are not supposed to be scaled, but the text overlay still
+   * needs to refer to a max if there are no normal monitors present
+   * Priority-wise, non-fixed monitor sources are always reported in preference
+   * to fixed-max sources
+   * On top of this, collect the curves together by monitor type so that they
+   * can be looped over later - easy to do this here while I'm already looping
+   * over everything, rather than maintaining a separate list on
+   * attaching/detaching monitors
+   * Unified maxes are needed even if the text overlay is not enabled */
+  mon_type_iterator it;
+  typename std::map<Glib::ustring, std::list<T*>>::iterator it_mon_type;
+  Glib::ustring mon_type;
+  for (typename std::list<T*>::iterator i = graph_elements.begin(),
+       end = graph_elements.end(); i != end; ++i)
+  {
+    if (plugin->get_viewer_monitor_type_sync_enabled())
+    {
+      // To get the real type, Monitor* must be dereferenced too...
+      mon_type = typeid(*((*i)->monitor)).name();
+    }
+    else mon_type = "All the same";
+
+    // If the monitor type hasn't yet been recorded, zero the maxes
+    it = monitor_maxes.find(mon_type);
+    if (it == monitor_maxes.end())
+      monitor_maxes[mon_type] = std::make_pair(0, 0);
+
+    if (!(*i)->monitor->fixed_max()
+        && (*i)->get_max_value() > monitor_maxes[mon_type].first)
+      monitor_maxes[mon_type].first = (*i)->get_max_value();
+    else if ((*i)->monitor->fixed_max()
+             && (*i)->monitor->max() > monitor_maxes[mon_type].second)
+      monitor_maxes[mon_type].second = (*i)->monitor->max();
+
+    // Record curve in monitor type list
+    it_mon_type = elems_by_mon_type.find(mon_type);
+    if (it_mon_type == elems_by_mon_type.end())
+      elems_by_mon_type[mon_type] = std::list<T*>();
+    elems_by_mon_type[mon_type].push_back(*i);
+  }
+
+  /* If a visualisation monitor type only has fixed maxes, then make sure the
+   * max value used is the fixed max
+   * Remember that a map iterator returns a pair of key,value!! */
+  for (mon_type_iterator i = monitor_maxes.begin(), end = monitor_maxes.end();
+       i != end; ++i)
+  {
+    if (i->second.first == 0 && i->second.second > 0)
+      i->second.first = i->second.second;
+  }
+
+  /* I tried to split out the text overlay path from non-text overlay, but as
+   * the visualisation maxes need to be tied to monitor types and not simply
+   * the biggest value across all monitors, keeping everything together in a
+   * type-based loop is still the best way */
+  if (text_overlay_enabled)
+  {
+    text_overlay_format_string = plugin->get_viewer_text_overlay_format_string();
+
+    /* Glib::ustring::npos is the strange way C++ flags as a failure to find a
+     * string */
+    if (text_overlay_format_string.find(monitor_full) != Glib::ustring::npos)
+      monitor_data_needed = true;
+    if (text_overlay_format_string.find(monitor_compact) != Glib::ustring::npos)
+      monitor_data_compact_needed = true;
+    if (text_overlay_format_string.find(graph_max_full) != Glib::ustring::npos)
+      graph_max_needed = true;
+    if (text_overlay_format_string.find(graph_max_compact) != Glib::ustring::npos)
+      graph_max_compact_needed = true;
+  }
+
+  /* Looping for all monitor types being tracked - seems to be automagically
+   * sorted in alphabetical order??
+   * Curves are both plotted and monitor values collated for the text overlay */
+  for (typename std::map<Glib::ustring,
+       std::list<T*>>::iterator i = elems_by_mon_type.begin(),
+       end = elems_by_mon_type.end(); i != end; ++i)
+  {
+    /* Loading up relevant max, at this stage fixed_max is irrelevant -
+     * remember std::map iterator returns a pair itself! */
+    max = monitor_maxes[i->first].first;
+
+    // Debug code
+    /*plugin->debug_log(
+          String::ucompose("CurveView::do_draw_loop: In top curve monitor types"
+                           " loop, monitor type '%1', max %2", i->first, max));*/
+
+    if (text_overlay_enabled)
+    {
+      // Resetting variables
+      monitor_data = monitor_data_compact = max_formatted
+          = max_formatted_compact = "";
+    }
+
+    for (typename std::list<T*>::iterator r = i->second.begin(), end = i->second.end();
+         r != end; ++r)
+    {
+      /* With separating out the monitor curves based on type, the max and
+       * units reported on can be correct */
+      if (text_overlay_enabled)
+      {
+        if (graph_max_needed && max_formatted.empty())
+          max_formatted += "Max:" + separator_string +
+              (*r)->monitor->format_value(max, false);
+        if (graph_max_compact_needed && max_formatted_compact.empty())
+          max_formatted_compact += "M:" + (*r)->monitor->format_value(max, true);
+
+        // Collecting a string of monitor data to overlay later
+        if (monitor_data_needed)
+        {
+          if (!(*r)->monitor->tag.empty())
+            tag_string = (*r)->monitor->tag + ":" + separator_string;
+          else
+            tag_string = "";
+
+          if (monitor_data.empty())
+          {
+            monitor_data = tag_string +
+                (*r)->monitor->format_value((*r)->monitor->value(), false);
+          }
+          else
+          {
+            monitor_data.append(separator_string + tag_string +
+                    (*r)->monitor->format_value((*r)->monitor->value(), false));
+          }
+        }
+        if (monitor_data_compact_needed)
+        {
+          if (!(*r)->monitor->tag.empty())
+            tag_string = (*r)->monitor->tag + ":";
+          else
+            tag_string = "";
+
+          if (monitor_data_compact.empty())
+          {
+            monitor_data_compact = tag_string +
+                (*r)->monitor->format_value((*r)->monitor->value(), true);
+          }
+          else
+          {
+            monitor_data_compact.append(separator_string + tag_string +
+                     (*r)->monitor->format_value((*r)->monitor->value(), true));
+          }
+        }
+      }
+
+      // Drawing the curves with the unified max value
+      //(*r)->draw(*canvas, width(), height(), max);
+      elems_and_maxes.push_back(std::make_pair(*r, max));
+    }
+
+    if (text_overlay_enabled)
+    {
+      /* Generation of text to overlay. This is now done on a per monitor type
+       * basis so that the maxes and units can be correctly reported on
+       * C++ does not have 'replace all' functionality??? Presumably using regex
+       * would be too slow for here? */
+      per_type_overlay_text = text_overlay_format_string;
+      if (monitor_data_needed)
+        find_and_replace(per_type_overlay_text, monitor_full, monitor_data);
+      if (monitor_data_compact_needed)
+        find_and_replace(per_type_overlay_text, monitor_compact,
+                         monitor_data_compact);
+      if (graph_max_needed)
+        find_and_replace(per_type_overlay_text, graph_max_full, max_formatted);
+      if (graph_max_compact_needed)
+        find_and_replace(per_type_overlay_text, graph_max_compact,
+                         max_formatted_compact);
+      if (overlay_text.empty())
+        overlay_text = per_type_overlay_text;
+      else
+        overlay_text += separator_string + per_type_overlay_text;
+    }
+  }
+
+  if (text_overlay_enabled)
+  {
+    // Checking if overlay is already initialised
+    if (!text_overlay)
+    {
+      /* Font and colour are required to output text, anchor is used to define
+       * what point on the item (canvas thing) to take as the 'centre' to then
+       * place on the canvas - e.g. ANCHOR_NW means the top-left corner is the
+       * 'centre' and the item will be placed exactly as you would expect it to.
+       * The default is GTK_ANCHOR_CENTER, hence text gets clipped in half top
+       * and side */
+      text_overlay = new Gnome::Canvas::Text(*canvas->root());
+      text_overlay->property_anchor() = Gtk::ANCHOR_NW;
+      text_overlay->property_text() = overlay_text;
+    }
+
+    // It is - updating if it has changed
+    else if (text_overlay->property_text() != overlay_text)
+      text_overlay->property_text() = overlay_text;
+
+    /* Setting/fixing changed font and colour - doing it here since the CurveView
+     * updates so frequently that its not worth also setting it directly from the
+     * UI etc */
+    Glib::ustring font_details = plugin->get_viewer_text_overlay_font();
+    if (font_details.empty())
+      font_details = "Sans 8";
+    if (text_overlay->property_font() != font_details)
+      text_overlay->property_font() = font_details;
+
+    unsigned int color = plugin->get_viewer_text_overlay_color();
+    if (text_overlay->property_fill_color_rgba() != color)
+      text_overlay->property_fill_color_rgba() = color;
+
+    // Positioning text
+    int x, y;
+    text_overlay_calc_position(x, y, plugin->get_viewer_text_overlay_position());
+    if (text_overlay->property_x() != x)
+      text_overlay->property_x() = x;
+    if (text_overlay->property_y() != y)
+      text_overlay->property_y() = y;
+  }
+  else
+  {
+    // Text overlay not enabled - ensure text is erased
+    if (text_overlay && text_overlay->property_text() != "")
+      text_overlay->property_text() = "";
+  }
+
+  return elems_and_maxes;
+}
+
+void CanvasView::text_overlay_calc_position(int& x, int& y,
+                                           TextOverlayPosition position)
+{
+  switch(position)
+  {
+    case top_left:
+      x = y = 0;
+      break;
+
+    case top_center:
+      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
+      y = 0;
+      break;
+
+    case top_right:
+      x = plugin->get_width() - text_overlay->property_text_width();
+      y = 0;
+      break;
+
+    case center:
+      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
+      y = (plugin->get_height() - text_overlay->property_text_height()) / 2;
+      break;
+
+    case bottom_left:
+      x = 0;
+      y = plugin->get_height() - text_overlay->property_text_height();
+      break;
+
+    case bottom_center:
+      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
+      y = plugin->get_height() - text_overlay->property_text_height();
+      break;
+
+    case bottom_right:
+      x = plugin->get_width() - text_overlay->property_text_width();
+      y = plugin->get_height() - text_overlay->property_text_height();
+      break;
+
+    default:
+      x = y = 0;
+      break;
+   }
+}
+
+const Glib::ustring CanvasView::text_overlay_position_to_string(
+      TextOverlayPosition position)
+{
+  switch(position)
+  {
+    case top_left:
+      return _("Top left");
+    case top_center:
+      return _("Top center");
+    case top_right:
+      return _("Top right");
+    case center:
+      return _("Center");
+    case bottom_left:
+      return _("Bottom left");
+    case bottom_center:
+      return _("Bottom center");
+    case bottom_right:
+      return _("Bottom right");
+    default:
+      return _("Top left");
+  }
+}
+
+/* Forced instantiation of template function to ensure the linker actually has
+ * something to link to from another compilation unit... without the include
+ * hell of moving the function implementation to the header */
+template class std::list<std::pair<Bar*, double>> CanvasView::process_mon_maxes_text_overlay(
+    typename std::list<Bar*> graph_elements);
+template class std::list<std::pair<Curve*, double>> CanvasView::process_mon_maxes_text_overlay(
+    typename std::list<Curve*> graph_elements);
+template class std::list<std::pair<Flame*, double>> CanvasView::process_mon_maxes_text_overlay(
+    typename std::list<Flame*> graph_elements);
+
diff --git a/src/canvas-view.hpp b/src/canvas-view.hpp
index c6e4021..0893c36 100644
--- a/src/canvas-view.hpp
+++ b/src/canvas-view.hpp
@@ -25,6 +25,7 @@
 #include <memory>
 
 #include <libgnomecanvasmm/canvas.h>
+#include <libgnomecanvasmm/text.h>
 #include <glibmm/ustring.h>
 #include <gtkmm/frame.h>
 
@@ -36,30 +37,53 @@ class Canvas;
 class CanvasView: public View, public sigc::trackable
 {
 public:
+
+  enum TextOverlayPosition {
+     top_left,
+     top_center,
+     top_right,
+     center,
+     bottom_left,
+     bottom_center,
+     bottom_right,
+     NUM_TEXT_OVERLAY_POSITIONS
+  };
+
   CanvasView(bool keeps_history);
   ~CanvasView();
 
+  /* Used to locate monitor type of interest in monitor_maxes during
+   * visualisation draw loop */
+  typedef std::map<Glib::ustring, std::pair<int, int>>::iterator
+      mon_type_iterator;
+
+  static const Glib::ustring text_overlay_position_to_string(
+      TextOverlayPosition position);
+
   static int const draw_interval;
   // for animation, number of drawings to break an update into
   static int const draw_iterations;
-  
+
 protected:
   virtual void do_display();
   virtual void do_update();
   virtual void do_set_background(unsigned int color);
   virtual void do_unset_background();
 
+  /* Included in the header as other compilation units need access to the
+   * definition in order to instantiate the relevant template function
+   * TODO: When I officially move to C++11, implement 'alias templates' as a
+   * form of typedefs that work with template declarations */
+  template <typename T>
+  std::list<std::pair<T*, double>> process_mon_maxes_text_overlay(
+      typename std::list<T*> graph_elements);
+
   int width() const;
   int height() const;
   void resize_canvas();   // resize canvas according to width and height
 
   int size;     // in pixels, width when vertical, else height
 
-  /* Used to locate monitor type of interest in monitor_maxes during
-   * visualisation draw loop */
-  typedef std::map<Glib::ustring, std::pair<int, int>>::iterator
-      mon_type_iterator;
-
   std::auto_ptr<Gnome::Canvas::Canvas> canvas;
 
   sigc::connection draw_timer;
@@ -67,6 +91,16 @@ protected:
 private:
   bool draw_loop();
   virtual void do_draw_loop() = 0;
+
+  void text_overlay_calc_position(int &x, int &y, TextOverlayPosition position);
+
+  Gnome::Canvas::Text *text_overlay;
+
+  // Text overlay format string substitution codes
+  static const Glib::ustring monitor_full;
+  static const Glib::ustring monitor_compact;
+  static const Glib::ustring graph_max_full;
+  static const Glib::ustring graph_max_compact;
 };
 
 #endif
diff --git a/src/column-view.cpp b/src/column-view.cpp
index 86999fe..0e7d260 100644
--- a/src/column-view.cpp
+++ b/src/column-view.cpp
@@ -19,41 +19,13 @@
 
 #include <cmath>
 
-#include <libgnomecanvasmm/pixbuf.h>
-
 #include "column-view.hpp"
 #include "plugin.hpp"
 #include "monitor.hpp"
-#include "value-history.hpp"
 
 #include "pixbuf-drawing.hpp"
 
 
-//
-// class ColumnGraph - represents the columns in a column diagram
-//
-
-class ColumnGraph
-{
-public:
-  ColumnGraph(Monitor *monitor, unsigned int color);
-
-  void update(unsigned int max_samples);  // Gather info from monitor
-  void draw(Gnome::Canvas::Canvas &canvas,  // Redraw columns on canvas
-      Plugin *plugin, int width, int height, double max);
-  double get_max_value();  // Used to get overall max across columns
-
-  Monitor *monitor;
-  
-private:
-  // A pixbuf is used for the columns
-  std::auto_ptr<Gnome::Canvas::Pixbuf> columns;
-
-  ValueHistory value_history;
-  int remaining_draws;
-  unsigned int color;
-};
-
 ColumnGraph::ColumnGraph(Monitor *m, unsigned int c)
   : monitor(m), value_history(m), remaining_draws(0), color(c)
 {
diff --git a/src/column-view.hpp b/src/column-view.hpp
index 110c085..945e433 100644
--- a/src/column-view.hpp
+++ b/src/column-view.hpp
@@ -25,12 +25,39 @@
 #include <memory>
 
 #include <libgnomecanvasmm/canvas.h>
+#include <libgnomecanvasmm/pixbuf.h>
+
 #include <glibmm/ustring.h>
 
 #include "canvas-view.hpp"
+#include "value-history.hpp"
+
+
+//
+// class ColumnGraph - represents the columns in a column diagram
+//
+
+class ColumnGraph
+{
+public:
+  ColumnGraph(Monitor *monitor, unsigned int color);
 
+  void update(unsigned int max_samples);  // Gather info from monitor
+  void draw(Gnome::Canvas::Canvas &canvas,  // Redraw columns on canvas
+      Plugin *plugin, int width, int height, double max);
+  double get_max_value();  // Used to get overall max across columns
+
+  Monitor *monitor;
+
+private:
+  // A pixbuf is used for the columns
+  std::auto_ptr<Gnome::Canvas::Pixbuf> columns;
+
+  ValueHistory value_history;
+  int remaining_draws;
+  unsigned int color;
+};
 
-class ColumnGraph;
 
 class ColumnView: public CanvasView
 {
diff --git a/src/curve-view.cpp b/src/curve-view.cpp
index 8214ea9..c06910d 100644
--- a/src/curve-view.cpp
+++ b/src/curve-view.cpp
@@ -22,7 +22,6 @@
 #include <typeinfo>  // For keeping track of monitor types in the visualisation
 #include <utility>  // For keeping track of monitor types in the visualisation
 
-#include <libgnomecanvasmm/line.h>
 #include <libgnomecanvasmm/point.h>
 
 #include "curve-view.hpp"
@@ -33,30 +32,6 @@
 #include "value-history.hpp"
 
 
-//
-// class Curve - represents a line curve
-//
-
-class Curve
-{
-public:
-  Curve(Monitor *monitor, unsigned int color);
-
-  void update(unsigned int max_samples);  // Gather info from monitor
-  void draw(Gnome::Canvas::Canvas &canvas,  // Redraw curve on canvas
-      int width, int height, double max);
-  double get_max_value();  // Used to get overall max across curves
-
-  Monitor *monitor;
-  
-private:
-  std::auto_ptr<Gnome::Canvas::Line> line;
-
-  ValueHistory value_history;
-  int remaining_draws;
-  unsigned int color;
-};
-
 Curve::Curve(Monitor *m, unsigned int c)
   : monitor(m), value_history(m), remaining_draws(0), color(c)
 {}
@@ -161,15 +136,8 @@ double Curve::get_max_value()
 
 int const CurveView::pixels_per_sample = 2;
 
-// Text overlay format string substitution codes
-const Glib::ustring CurveView::monitor_full = "%M";
-const Glib::ustring CurveView::monitor_compact = "%m";
-const Glib::ustring CurveView::graph_max_full = "%A";
-const Glib::ustring CurveView::graph_max_compact = "%a";
-
-
 CurveView::CurveView()
-  : CanvasView(true), text_overlay(NULL)
+  : CanvasView(true)
 {
 }
 
@@ -177,7 +145,6 @@ CurveView::~CurveView()
 {
   for (curve_iterator i = curves.begin(), end = curves.end(); i != end; ++i)
     delete *i;
-  delete text_overlay;
 }
 
 void CurveView::do_update()
@@ -270,311 +237,16 @@ void CurveView::do_detach(Monitor *monitor)
 
 void CurveView::do_draw_loop()
 {
-  double max;
-
-  // Monitor maxes maintained as a pair of <normal max>, <fixed max>
-  std::map<Glib::ustring, std::pair<int, int>> monitor_maxes;
-
-  // Monitors collected by type to allow easy access to separated data sets
-  std::map<Glib::ustring, std::list<Curve*>> curves_by_mon_type;
-
-  Glib::ustring max_formatted, max_formatted_compact, monitor_data,
-      monitor_data_compact, overlay_text, per_type_overlay_text,
-      text_overlay_format_string, tag_string,
-      separator_string = plugin->get_viewer_text_overlay_separator();
-  bool graph_max_needed = false, graph_max_compact_needed = false,
-      monitor_data_needed = false, monitor_data_compact_needed = false,
-      text_overlay_enabled = plugin->get_viewer_text_overlay_enabled();
-
-  /* Obtain maximum value of all curves in the view on a per monitor type basis
-   * but only when the user wants visualisations to be split by type,
-   * separately tracking fixed maxes incase all monitors are fixed. Graphs with
-   * fixed monitors are not supposed to be scaled, but the text overlay still
-   * needs to refer to a max if there are no normal monitors present
-   * Priority-wise, non-fixed monitor sources are always reported in preference
-   * to fixed-max sources
-   * On top of this, collect the curves together by monitor type so that they
-   * can be looped over later - easy to do this here while I'm already looping
-   * over everything, rather than maintaining a separate list on
-   * attaching/detaching monitors
-   * Unified maxes are needed even if the text overlay is not enabled */
-  mon_type_iterator it;
-  curves_mon_type_iterator it_mon_type;
-  Glib::ustring mon_type;
-  for (curve_iterator i = curves.begin(), end = curves.end(); i != end; ++i)
-  {
-    if (plugin->get_viewer_monitor_type_sync_enabled())
-    {
-      // To get the real type, Monitor* must be dereferenced too...
-      mon_type = typeid(*((*i)->monitor)).name();
-    }
-    else mon_type = "All the same";
-
-    // If the monitor type hasn't yet been recorded, zero the maxes
-    it = monitor_maxes.find(mon_type);
-    if (it == monitor_maxes.end())
-      monitor_maxes[mon_type] = std::make_pair(0, 0);
-
-    if (!(*i)->monitor->fixed_max()
-        && (*i)->get_max_value() > monitor_maxes[mon_type].first)
-      monitor_maxes[mon_type].first = (*i)->get_max_value();
-    else if ((*i)->monitor->fixed_max()
-             && (*i)->monitor->max() > monitor_maxes[mon_type].second)
-      monitor_maxes[mon_type].second = (*i)->monitor->max();
-
-    // Record curve in monitor type list
-    it_mon_type = curves_by_mon_type.find(mon_type);
-    if (it_mon_type == curves_by_mon_type.end())
-      curves_by_mon_type[mon_type] = std::list<Curve*>();
-    curves_by_mon_type[mon_type].push_back(*i);
-  }
-
-  /* If a visualisation monitor type only has fixed maxes, then make sure the
-   * max value used is the fixed max
-   * Remember that a map iterator returns a pair of key,value!! */
-  for (mon_type_iterator i = monitor_maxes.begin(), end = monitor_maxes.end();
-       i != end; ++i)
-  {
-    if (i->second.first == 0 && i->second.second > 0)
-      i->second.first = i->second.second;
-  }
-
-  /* I tried to split out the text overlay path from non-text overlay, but as
-   * the visualisation maxes need to be tied to monitor types and not simply
-   * the biggest value across all monitors, keeping everything together in a
-   * type-based loop is still the best way */
-  if (text_overlay_enabled)
-  {
-    text_overlay_format_string = plugin->get_viewer_text_overlay_format_string();
-
-    /* Glib::ustring::npos is the strange way C++ flags as a failure to find a
-     * string */
-    if (text_overlay_format_string.find(monitor_full) != Glib::ustring::npos)
-      monitor_data_needed = true;
-    if (text_overlay_format_string.find(monitor_compact) != Glib::ustring::npos)
-      monitor_data_compact_needed = true;
-    if (text_overlay_format_string.find(graph_max_full) != Glib::ustring::npos)
-      graph_max_needed = true;
-    if (text_overlay_format_string.find(graph_max_compact) != Glib::ustring::npos)
-      graph_max_compact_needed = true;
-  }
-
-  /* Looping for all monitor types being tracked - seems to be automagically
-   * sorted in alphabetical order??
-   * Curves are both plotted and monitor values collated for the text overlay */
-  for (curves_mon_type_iterator i = curves_by_mon_type.begin(),
-       end = curves_by_mon_type.end(); i != end; ++i)
-  {
-    /* Loading up relevant max, at this stage fixed_max is irrelevant -
-     * remember std::map iterator returns a pair itself! */
-    max = monitor_maxes[i->first].first;
-
-    // Debug code
-    /*plugin->debug_log(
-          String::ucompose("CurveView::do_draw_loop: In top curve monitor types"
-                           " loop, monitor type '%1', max %2", i->first, max));*/
-
-    if (text_overlay_enabled)
-    {
-      // Resetting variables
-      monitor_data = monitor_data_compact = max_formatted
-          = max_formatted_compact = "";
-    }
-
-    for (curve_iterator r = i->second.begin(), end = i->second.end();
-         r != end; ++r)
-    {
-      /* With separating out the monitor curves based on type, the max and
-       * units reported on can be correct */
-      if (text_overlay_enabled)
-      {
-        if (graph_max_needed && max_formatted.empty())
-          max_formatted += "Max:" + separator_string +
-              (*r)->monitor->format_value(max, false);
-        if (graph_max_compact_needed && max_formatted_compact.empty())
-          max_formatted_compact += "M:" + (*r)->monitor->format_value(max, true);
-
-        // Collecting a string of monitor data to overlay later
-        if (monitor_data_needed)
-        {
-          if (!(*r)->monitor->tag.empty())
-            tag_string = (*r)->monitor->tag + ":" + separator_string;
-          else
-            tag_string = "";
-
-          if (monitor_data.empty())
-          {
-            monitor_data = tag_string +
-                (*r)->monitor->format_value((*r)->monitor->value(), false);
-          }
-          else
-          {
-            monitor_data.append(separator_string + tag_string +
-                    (*r)->monitor->format_value((*r)->monitor->value(), false));
-          }
-        }
-        if (monitor_data_compact_needed)
-        {
-          if (!(*r)->monitor->tag.empty())
-            tag_string = (*r)->monitor->tag + ":";
-          else
-            tag_string = "";
-
-          if (monitor_data_compact.empty())
-          {
-            monitor_data_compact = tag_string +
-                (*r)->monitor->format_value((*r)->monitor->value(), true);
-          }
-          else
-          {
-            monitor_data_compact.append(separator_string + tag_string +
-                     (*r)->monitor->format_value((*r)->monitor->value(), true));
-          }
-        }
-      }
-
-      // Drawing the curves with the unified max value
-      (*r)->draw(*canvas, width(), height(), max);
-    }
-
-    if (text_overlay_enabled)
-    {
-      /* Generation of text to overlay. This is now done on a per monitor type
-       * basis so that the maxes and units can be correctly reported on
-       * C++ does not have 'replace all' functionality??? Presumably using regex
-       * would be too slow for here? */
-      per_type_overlay_text = text_overlay_format_string;
-      if (monitor_data_needed)
-        find_and_replace(per_type_overlay_text, monitor_full, monitor_data);
-      if (monitor_data_compact_needed)
-        find_and_replace(per_type_overlay_text, monitor_compact,
-                         monitor_data_compact);
-      if (graph_max_needed)
-        find_and_replace(per_type_overlay_text, graph_max_full, max_formatted);
-      if (graph_max_compact_needed)
-        find_and_replace(per_type_overlay_text, graph_max_compact,
-                         max_formatted_compact);
-      if (overlay_text.empty())
-        overlay_text = per_type_overlay_text;
-      else
-        overlay_text += separator_string + per_type_overlay_text;
-    }
-  }
-
-  if (text_overlay_enabled)
-  {
-    // Checking if overlay is already initialised
-    if (!text_overlay)
-    {
-      /* Font and colour are required to output text, anchor is used to define
-       * what point on the item (canvas thing) to take as the 'centre' to then
-       * place on the canvas - e.g. ANCHOR_NW means the top-left corner is the
-       * 'centre' and the item will be placed exactly as you would expect it to.
-       * The default is GTK_ANCHOR_CENTER, hence text gets clipped in half top
-       * and side */
-      text_overlay = new Gnome::Canvas::Text(*canvas->root());
-      text_overlay->property_anchor() = Gtk::ANCHOR_NW;
-      text_overlay->property_text() = overlay_text;
-    }
-
-    // It is - updating if it has changed
-    else if (text_overlay->property_text() != overlay_text)
-      text_overlay->property_text() = overlay_text;
-
-    /* Setting/fixing changed font and colour - doing it here since the CurveView
-     * updates so frequently that its not worth also setting it directly from the
-     * UI etc */
-    Glib::ustring font_details = plugin->get_viewer_text_overlay_font();
-    if (font_details.empty())
-      font_details = "Sans 8";
-    if (text_overlay->property_font() != font_details)
-      text_overlay->property_font() = font_details;
-
-    unsigned int color = plugin->get_viewer_text_overlay_color();
-    if (text_overlay->property_fill_color_rgba() != color)
-      text_overlay->property_fill_color_rgba() = color;
-
-    // Positioning text
-    int x, y;
-    text_overlay_calc_position(x, y, plugin->get_viewer_text_overlay_position());
-    if (text_overlay->property_x() != x)
-      text_overlay->property_x() = x;
-    if (text_overlay->property_y() != y)
-      text_overlay->property_y() = y;
-  }
-  else
-  {
-    // Text overlay not enabled - ensure text is erased
-    if (text_overlay && text_overlay->property_text() != "")
-      text_overlay->property_text() = "";
-  }
-}
-
-const Glib::ustring CurveView::text_overlay_position_to_string(
-      TextOverlayPosition position)
-{
-  switch(position)
-  {
-    case top_left:
-      return _("Top left");
-    case top_center:
-      return _("Top center");
-    case top_right:
-      return _("Top right");
-    case center:
-      return _("Center");
-    case bottom_left:
-      return _("Bottom left");
-    case bottom_center:
-      return _("Bottom center");
-    case bottom_right:
-      return _("Bottom right");
-    default:
-      return _("Top left");
-  }
-}
-
-void CurveView::text_overlay_calc_position(int& x, int& y,
-                                           TextOverlayPosition position)
-{
-  switch(position)
-  {
-    case top_left:
-      x = y = 0;
-      break;
 
-    case top_center:
-      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
-      y = 0;
-      break;
-
-    case top_right:
-      x = plugin->get_width() - text_overlay->property_text_width();
-      y = 0;
-      break;
-
-    case center:
-      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
-      y = (plugin->get_height() - text_overlay->property_text_height()) / 2;
-      break;
-
-    case bottom_left:
-      x = 0;
-      y = plugin->get_height() - text_overlay->property_text_height();
-      break;
-
-    case bottom_center:
-      x = (plugin->get_width() - text_overlay->property_text_width()) / 2;
-      y = plugin->get_height() - text_overlay->property_text_height();
-      break;
-
-    case bottom_right:
-      x = plugin->get_width() - text_overlay->property_text_width();
-      y = plugin->get_height() - text_overlay->property_text_height();
-      break;
-
-    default:
-      x = y = 0;
-      break;
-   }
+  /* Generating list of curves with correct maxima (unified and potentially
+   * grouped by monitor type) to then draw, and triggering processing of text
+   * overlay on the CanvasView if the user desires */
+  std::list<std::pair<Curve*, double>> curves_and_maxes =
+      process_mon_maxes_text_overlay(curves);
+
+  /* Looping for all curves to draw - in the std::pair, first is the Curve,
+   * second is the max */
+  for (std::list<std::pair<Curve*, double>>::iterator i = curves_and_maxes.begin(),
+       end = curves_and_maxes.end(); i != end; ++i)
+    i->first->draw(*canvas, width(), height(), i->second);
 }
diff --git a/src/curve-view.hpp b/src/curve-view.hpp
index 31f1b21..e18725f 100644
--- a/src/curve-view.hpp
+++ b/src/curve-view.hpp
@@ -23,13 +23,38 @@
 #include <memory>
 
 #include <libgnomecanvasmm/canvas.h>
+#include <libgnomecanvasmm/line.h>
 #include <libgnomecanvasmm/text.h>
 #include <glibmm/ustring.h>
 
 #include "canvas-view.hpp"
+#include "value-history.hpp"
 
 
-class Curve;
+//
+// class Curve - represents a line curve
+//
+
+class Curve
+{
+public:
+  Curve(Monitor *monitor, unsigned int color);
+
+  void update(unsigned int max_samples);  // Gather info from monitor
+  void draw(Gnome::Canvas::Canvas &canvas,  // Redraw curve on canvas
+      int width, int height, double max);
+  double get_max_value();  // Used to get overall max across curves
+
+  Monitor *monitor;
+
+private:
+  std::auto_ptr<Gnome::Canvas::Line> line;
+
+  ValueHistory value_history;
+  int remaining_draws;
+  unsigned int color;
+};
+
 
 class CurveView: public CanvasView
 {
@@ -39,44 +64,16 @@ public:
   
   static int const pixels_per_sample;
 
-  enum TextOverlayPosition {
-     top_left,
-     top_center,
-     top_right,
-     center,
-     bottom_left,
-     bottom_center,
-     bottom_right,
-     NUM_TEXT_OVERLAY_POSITIONS
-  };
-
-  static const Glib::ustring text_overlay_position_to_string(
-      TextOverlayPosition position);
-
 private:
   virtual void do_update();
   virtual void do_attach(Monitor *monitor);
   virtual void do_detach(Monitor *monitor);
   virtual void do_draw_loop();
 
-  void text_overlay_calc_position(int &x, int &y, TextOverlayPosition position);
-
   // Must be destroyed before the canvas
   typedef std::list<Curve *> curve_sequence;
   typedef curve_sequence::iterator curve_iterator;
   curve_sequence curves;
-
-  // Used to move through curves maintained per monitor type
-  typedef std::map<Glib::ustring, std::list<Curve*>>::iterator
-      curves_mon_type_iterator;
-
-  Gnome::Canvas::Text *text_overlay;
-
-  // Text overlay format string substitution codes
-  static const Glib::ustring monitor_full;
-  static const Glib::ustring monitor_compact;
-  static const Glib::ustring graph_max_full;
-  static const Glib::ustring graph_max_compact;
 };
 
 #endif
diff --git a/src/flame-view.cpp b/src/flame-view.cpp
index 67d9cab..b868d1a 100644
--- a/src/flame-view.cpp
+++ b/src/flame-view.cpp
@@ -21,8 +21,6 @@
 #include <cmath>
 #include <vector>
 
-#include <libgnomecanvasmm/pixbuf.h>
-
 #include "pixbuf-drawing.hpp"
 
 #include "flame-view.hpp"
@@ -30,35 +28,6 @@
 #include "monitor.hpp"
 
 
-//
-// class Flame - represents a flame layer
-//
-
-class Flame
-{
-public:
-  Flame(Monitor *monitor, unsigned int color);
-
-  void burn(double overall_max);
-  double get_max_value();
-  void update(Gnome::Canvas::Canvas &canvas,
-        Plugin *plugin, int width, int height, int no, int total);
-  
-  Monitor *monitor;
-  
-private:
-  std::auto_ptr<Gnome::Canvas::Pixbuf> flame;
-
-  double value, max;
-
-  std::vector<unsigned char> fuel;
-  int next_refuel;
-  int cooling;      // cooling factor
-
-  void recompute_fuel(double overall_max);
-  unsigned int color;
-};
-
 Flame::Flame(Monitor *m, unsigned int c)
   : monitor(m), value(0), next_refuel(0), color(c)
 {}
diff --git a/src/flame-view.hpp b/src/flame-view.hpp
index e2db676..ea9d76a 100644
--- a/src/flame-view.hpp
+++ b/src/flame-view.hpp
@@ -26,12 +26,42 @@
 #include <memory>
 
 #include <libgnomecanvasmm/canvas.h>
+#include <libgnomecanvasmm/pixbuf.h>
+
 #include <glibmm/ustring.h>
 
 #include "canvas-view.hpp"
 
 
-class Flame;
+//
+// class Flame - represents a flame layer
+//
+
+class Flame
+{
+public:
+  Flame(Monitor *monitor, unsigned int color);
+
+  void burn(double overall_max);
+  double get_max_value();
+  void update(Gnome::Canvas::Canvas &canvas,
+        Plugin *plugin, int width, int height, int no, int total);
+
+  Monitor *monitor;
+
+private:
+  std::auto_ptr<Gnome::Canvas::Pixbuf> flame;
+
+  double value, max;
+
+  std::vector<unsigned char> fuel;
+  int next_refuel;
+  int cooling;      // cooling factor
+
+  void recompute_fuel(double overall_max);
+  unsigned int color;
+};
+
 
 class FlameView: public CanvasView
 {
diff --git a/src/plugin.cpp b/src/plugin.cpp
index 4b4e0ea..982d66a 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -167,7 +167,7 @@ Plugin::Plugin(XfcePanelPlugin *xfce_plugin)
   viewer_text_overlay_separator(" "),
   viewer_text_overlay_font(""),
   viewer_text_overlay_color(0x000000FF),
-  viewer_text_overlay_position(CurveView::top_left),
+  viewer_text_overlay_position(CanvasView::top_left),
   viewer_monitor_type_sync_enabled(true)
 {
   // Search for settings file
@@ -211,10 +211,10 @@ Plugin::Plugin(XfcePanelPlugin *xfce_plugin)
       "viewer_monitor_type_sync_enabled", viewer_monitor_type_sync_enabled);
 
     // Enum is validated in set_viewer_text_overlay_position
-    CurveView::TextOverlayPosition text_overlay_position =
-        static_cast<CurveView::TextOverlayPosition>(
+    CanvasView::TextOverlayPosition text_overlay_position =
+        static_cast<CanvasView::TextOverlayPosition>(
           xfce_rc_read_int_entry(settings_ro, "viewer_text_overlay_position",
-                                 CurveView::top_left));
+                                 CanvasView::top_left));
     set_viewer_text_overlay_position(text_overlay_position);
   }
   
@@ -631,21 +631,21 @@ void Plugin::set_viewer_text_overlay_color(const unsigned int color)
   viewer_text_overlay_color = color;
 }
 
-const CurveView::TextOverlayPosition Plugin::get_viewer_text_overlay_position()
+const CanvasView::TextOverlayPosition Plugin::get_viewer_text_overlay_position()
 {
   return viewer_text_overlay_position;
 }
 
-void Plugin::set_viewer_text_overlay_position(CurveView::TextOverlayPosition
+void Plugin::set_viewer_text_overlay_position(CanvasView::TextOverlayPosition
                                       position)
 {
   // Validating input - an enum does not enforce a range!!
-  if (position < CurveView::top_left ||
-      position >= CurveView::NUM_TEXT_OVERLAY_POSITIONS)
+  if (position < CanvasView::top_left ||
+      position >= CanvasView::NUM_TEXT_OVERLAY_POSITIONS)
   {
     std::cerr << "Plugin::set_viewer_text_overlay_position was called with an "
                  "invalid position: " << position << "!\n";
-    position = CurveView::top_left;
+    position = CanvasView::top_left;
   }
 
   viewer_text_overlay_position = position;
diff --git a/src/plugin.hpp b/src/plugin.hpp
index f4aaa3f..a8169e0 100644
--- a/src/plugin.hpp
+++ b/src/plugin.hpp
@@ -85,8 +85,8 @@ public:
   void set_viewer_text_overlay_font(const Glib::ustring font_details);
   const unsigned int get_viewer_text_overlay_color() const;
   void set_viewer_text_overlay_color(const unsigned int color);
-  const CurveView::TextOverlayPosition get_viewer_text_overlay_position();
-  void set_viewer_text_overlay_position(CurveView::TextOverlayPosition
+  const CanvasView::TextOverlayPosition get_viewer_text_overlay_position();
+  void set_viewer_text_overlay_position(CanvasView::TextOverlayPosition
                                         position);
 
   /* Force update allows for this to be called to essentially reload the view
@@ -144,7 +144,7 @@ private:
   Glib::ustring viewer_text_overlay_format_string, viewer_text_overlay_separator,
                 viewer_text_overlay_font;
   unsigned int viewer_text_overlay_color;
-  CurveView::TextOverlayPosition viewer_text_overlay_position;
+  CanvasView::TextOverlayPosition viewer_text_overlay_position;
 
   unsigned int background_color;
   int viewer_size, next_color;
diff --git a/src/preferences-window.cpp b/src/preferences-window.cpp
index 4d3149e..c2d277d 100644
--- a/src/preferences-window.cpp
+++ b/src/preferences-window.cpp
@@ -31,7 +31,7 @@
 #include "gui-helpers.hpp"
 #include "plugin.hpp"
 #include "monitor.hpp"
-#include "curve-view.hpp"
+#include "canvas-view.hpp"
 #include "i18n.hpp"
 
 
@@ -253,15 +253,15 @@ PreferencesWindow::PreferencesWindow(Plugin &plugin_, monitor_seq monitors)
   monitor_treeview->get_selection()->unselect_all();
 
   // Populating text overlay position combobox and selecting the correct position
-  CurveView::TextOverlayPosition current_pos, position =
+  CanvasView::TextOverlayPosition current_pos, position =
       plugin.get_viewer_text_overlay_position();
   store_iter i;
-  for (int r = 0; r < CurveView::NUM_TEXT_OVERLAY_POSITIONS; ++r)
+  for (int r = 0; r < CanvasView::NUM_TEXT_OVERLAY_POSITIONS; ++r)
   {
-    current_pos = static_cast<CurveView::TextOverlayPosition>(r);
+    current_pos = static_cast<CanvasView::TextOverlayPosition>(r);
 
     i = text_overlay_position_store->append();
-    (*i)[topc.position] = CurveView::text_overlay_position_to_string(current_pos);
+    (*i)[topc.position] = CanvasView::text_overlay_position_to_string(current_pos);
 
     if (position == current_pos)
       text_overlay_position_combobox->set_active(r);
@@ -919,7 +919,7 @@ void PreferencesWindow::on_text_overlay_position_combobox_changed()
   int position = text_overlay_position_combobox->get_active_row_number();
 
   plugin.set_viewer_text_overlay_position(
-        static_cast<CurveView::TextOverlayPosition>(position));
+        static_cast<CanvasView::TextOverlayPosition>(position));
 
   // Search for a writeable settings file, create one if it doesnt exist */
   gchar* file = xfce_panel_plugin_save_location(plugin.xfce_plugin, true);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list