add initial (untested) implementation of canvas ruler item
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 11 Jun 2014 16:24:43 +0000 (12:24 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 12 Jun 2014 03:54:28 +0000 (23:54 -0400)
libs/canvas/canvas/ruler.h [new file with mode: 0644]
libs/canvas/ruler.cc [new file with mode: 0644]

diff --git a/libs/canvas/canvas/ruler.h b/libs/canvas/canvas/ruler.h
new file mode 100644 (file)
index 0000000..ac72245
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+    Copyright (C) 2014 Paul Davis
+
+    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 __CANVAS_RULER_H__
+#define __CANVAS_RULER_H__
+
+#include <string>
+#include <vector>
+
+#include "canvas/item.h"
+#include "canvas/fill.h"
+#include "canvas/outline.h"
+
+namespace ArdourCanvas
+{
+       
+class LIBCANVAS_API Ruler : virtual public Item, public Fill, public Outline
+{
+public:
+       struct Mark {
+               enum Style {
+                       Major,
+                       Minor,
+                       Micro
+               };
+               std::string label;
+               double position;
+               Style  style;
+       };
+       
+       struct Metric {
+               Metric () : units_per_pixel (0) {}
+               virtual ~Metric() {}
+
+               double units_per_pixel;
+
+               /* lower and upper and sample positions, which are also canvas coordinates
+                */
+               
+               virtual int get_marks (std::vector<Mark>&, double lower, double upper, int maxchars) const = 0;
+       };
+       
+       Ruler (Group *, const Metric& m);
+       
+       void set_range (double lower, double upper);
+       void set_size (Rect const&);
+
+       void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const;
+       void compute_bounding_box () const;
+       
+private:
+       const Metric& _metric;
+       Rect          _rect;
+
+       /* lower and upper and sample positions, which are also canvas coordinates
+        */
+
+       Coord         _lower;
+       Coord         _upper;
+};
+
+}
+
+
+#endif
diff --git a/libs/canvas/ruler.cc b/libs/canvas/ruler.cc
new file mode 100644 (file)
index 0000000..ac46249
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+    Copyright (C) 2014 Paul Davis
+    Author: Carl Hetherington <cth@carlh.net>
+
+    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 <algorithm>
+#include <cairomm/context.h>
+#include "pbd/compose.h"
+#include "canvas/ruler.h"
+#include "canvas/types.h"
+#include "canvas/debug.h"
+#include "canvas/utils.h"
+#include "canvas/canvas.h"
+
+using namespace std;
+using namespace ArdourCanvas;
+
+Ruler::Ruler (Group *p, const Metric& m)
+       : Item (p)
+       , Fill (p)
+       , Outline (p)
+       , _metric (m)
+{
+}
+
+void
+Ruler::set_range (double l, double u)
+{
+       _lower = l;
+       _upper = u;
+}
+
+void
+Ruler::set_size (Rect const & area)
+{
+       if (_rect != area) {
+               begin_visual_change ();
+               _rect = area;
+               _bounding_box_dirty = true;
+               end_visual_change ();
+       }
+}
+
+void
+Ruler::compute_bounding_box () const
+{
+       if (!_rect.empty()) {
+               _bounding_box = _rect;
+       }
+
+       _bounding_box_dirty = false;
+}
+
+void
+Ruler::render (Rect const & area, Cairo::RefPtr<Cairo::Context> cr) const
+{
+       Rect self (item_to_window (_rect));
+       boost::optional<Rect> i = self.intersection (area);
+       if (!i) {
+               return;
+       }
+
+       Rect intersection (i.get());
+
+       vector<Mark> marks;
+       Distance height = self.height();
+
+       _metric.get_marks (marks, _lower, _upper, 50);
+
+       /* draw background */
+
+       setup_fill_context (cr);
+       cr->rectangle (intersection.x0, intersection.y0, intersection.width(), intersection.height());
+       cr->fill ();
+
+       /* draw ticks */
+       
+       setup_outline_context (cr);
+
+       for (vector<Mark>::const_iterator m = marks.begin(); m != marks.end(); ++m) {
+               Duple pos;
+
+               pos.x = self.x0 + ((m->position - _lower) / _metric.units_per_pixel);
+               pos.y = self.y1; /* bottom edge */
+               
+               cr->move_to (pos.x, pos.y);
+               
+               switch (m->style) {
+               case Mark::Major:
+                       cr->rel_move_to (0, -height);
+                       break;
+               case Mark::Minor:
+                       cr->rel_move_to (0, -(height/2.0));
+                       break;
+               case Mark::Micro:
+                       cr->rel_move_to (0, pos.y-(height/4.0));
+                       break;
+               }
+               cr->stroke ();
+       }
+
+       /* done! */
+}