diff options
Diffstat (limited to 'libs/canvas/canvas')
-rw-r--r-- | libs/canvas/canvas/arrow.h | 88 | ||||
-rw-r--r-- | libs/canvas/canvas/canvas.h | 198 | ||||
-rw-r--r-- | libs/canvas/canvas/debug.h | 30 | ||||
-rw-r--r-- | libs/canvas/canvas/fill.h | 35 | ||||
-rw-r--r-- | libs/canvas/canvas/flag.h | 27 | ||||
-rw-r--r-- | libs/canvas/canvas/group.h | 58 | ||||
-rw-r--r-- | libs/canvas/canvas/item.h | 180 | ||||
-rw-r--r-- | libs/canvas/canvas/item_factory.h | 9 | ||||
-rw-r--r-- | libs/canvas/canvas/line.h | 44 | ||||
-rw-r--r-- | libs/canvas/canvas/line_set.h | 38 | ||||
-rw-r--r-- | libs/canvas/canvas/lookup_table.h | 66 | ||||
-rw-r--r-- | libs/canvas/canvas/outline.h | 74 | ||||
-rw-r--r-- | libs/canvas/canvas/pixbuf.h | 27 | ||||
-rw-r--r-- | libs/canvas/canvas/poly_item.h | 30 | ||||
-rw-r--r-- | libs/canvas/canvas/poly_line.h | 21 | ||||
-rw-r--r-- | libs/canvas/canvas/polygon.h | 22 | ||||
-rw-r--r-- | libs/canvas/canvas/rectangle.h | 69 | ||||
-rw-r--r-- | libs/canvas/canvas/root_group.h | 21 | ||||
-rw-r--r-- | libs/canvas/canvas/text.h | 32 | ||||
-rw-r--r-- | libs/canvas/canvas/types.h | 88 | ||||
-rw-r--r-- | libs/canvas/canvas/utils.h | 8 | ||||
-rw-r--r-- | libs/canvas/canvas/wave_view.h | 119 |
22 files changed, 1284 insertions, 0 deletions
diff --git a/libs/canvas/canvas/arrow.h b/libs/canvas/canvas/arrow.h new file mode 100644 index 0000000000..a5a338a3ba --- /dev/null +++ b/libs/canvas/canvas/arrow.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2011 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. + +*/ + +/** @file canvas/arrow.h + * @brief Declaration of the Arrow canvas object. + */ + +#ifndef __CANVAS_ARROW_H__ +#define __CANVAS_ARROW_H__ + +#include "canvas/group.h" + +namespace ArdourCanvas { + +class Line; +class Polygon; + +/** A composite item which draws a line with arrow heads + * at either or both ends. + * + * The arrow heads are identified by the indices 0 and 1; + * head 0 is at the (x0, y0) end of the line, and head 1 + * at the (x1, y1) end. + * + * @todo Draws vertical lines only; could be generalised + * to draw lines at any angle. + */ + +class Arrow : public Group +{ +public: + Arrow (Group *); + + void set_show_head (int, bool); + void set_head_outward (int, bool); + void set_head_height (int, Distance); + void set_head_width (int, Distance); + void set_outline_width (Distance); + void set_color (Color); + + Coord x () const; + Coord y1 () const; + + void set_x (Coord); + void set_y0 (Coord); + void set_y1 (Coord); + +private: + void setup_polygon (int); + + /** Representation of a single arrow head */ + struct Head { + Polygon* polygon; ///< the polygon which represents its shape + bool show; ///< true if this head should be visible + bool outward; ///< true if this head points out from the line + Distance height; ///< the height of the head + Distance width; ///< the maximum width of the head + }; + + /** our arrow heads; _heads[0] is at the (x0, y0) end of the line, + * and _heads[1] at the (x1, y1) end. + */ + Head _heads[2]; + + /** our line */ + Line* _line; +}; + +} + +#endif diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h new file mode 100644 index 0000000000..a4e76bf3f8 --- /dev/null +++ b/libs/canvas/canvas/canvas.h @@ -0,0 +1,198 @@ +/* + Copyright (C) 2011 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. + +*/ + +/** @file canvas/canvas.h + * @brief Declaration of the main canvas classes. + */ + +#ifndef __CANVAS_CANVAS_H__ +#define __CANVAS_CANVAS_H__ + +#include <gdkmm/window.h> +#include <gtkmm/eventbox.h> +#include <gtkmm/viewport.h> +#include <cairomm/surface.h> +#include <cairomm/context.h> +#include "pbd/signals.h" +#include "canvas/root_group.h" + +class XMLTree; + +namespace ArdourCanvas +{ + +class Rect; +class Group; + +/** The base class for our different types of canvas. + * + * A canvas is an area which holds a collection of canvas items, which in + * turn represent shapes, text, etc. + * + * The canvas has an arbitrarily large area, and is addressed in coordinates + * of screen pixels, with an origin of (0, 0) at the top left. x increases + * rightwards and y increases downwards. + */ + +class Canvas +{ +public: + Canvas (); + Canvas (XMLTree const *); + virtual ~Canvas () {} + + /** called to request a redraw of an area of the canvas */ + virtual void request_redraw (Rect const &) = 0; + /** called to ask the canvas to request a particular size from its host */ + virtual void request_size (Duple) = 0; + /** called to ask the canvas' host to `grab' an item */ + virtual void grab (Item *) = 0; + /** called to ask the canvas' host to `ungrab' any grabbed item */ + virtual void ungrab () = 0; + + void render (Rect const &, Cairo::RefPtr<Cairo::Context> const &) const; + + /** @return root group */ + Group* root () { + return &_root; + } + + /** Called when an item is being destroyed */ + virtual void item_going_away (Item *, boost::optional<Rect>) {} + void item_shown_or_hidden (Item *); + void item_changed (Item *, boost::optional<Rect>); + void item_moved (Item *, boost::optional<Rect>); + + XMLTree* get_state () const; + + virtual Cairo::RefPtr<Cairo::Context> context () = 0; + + std::list<Rect> const & renders () const { + return _renders; + } + + void set_log_renders (bool log) { + _log_renders = log; + } + +protected: + void queue_draw_item_area (Item *, Rect); + + /** our root group */ + RootGroup _root; + + mutable std::list<Rect> _renders; + bool _log_renders; +}; + +/** A Canvas which renders onto an in-memory pixbuf. In Ardour's context, + * this is most useful for testing. + */ +class ImageCanvas : public Canvas +{ +public: + ImageCanvas (Duple size = Duple (1024, 1024)); + ImageCanvas (XMLTree const *, Duple size = Duple (1024, 1024)); + + void request_redraw (Rect const &) { + /* XXX */ + } + + void request_size (Duple) { + /* XXX */ + } + + void grab (Item *) {} + void ungrab () {} + + void render_to_image (Rect const &) const; + void clear (); + void write_to_png (std::string const &); + + Cairo::RefPtr<Cairo::Context> context (); + +private: + /** our Cairo surface */ + Cairo::RefPtr<Cairo::Surface> _surface; + /** our Cairo context */ + Cairo::RefPtr<Cairo::Context> _context; +}; + +/** A canvas which renders onto a GTK EventBox */ +class GtkCanvas : public Canvas, public Gtk::EventBox +{ +public: + GtkCanvas (); + GtkCanvas (XMLTree const *); + + void request_redraw (Rect const &); + void request_size (Duple); + void grab (Item *); + void ungrab (); + + Cairo::RefPtr<Cairo::Context> context (); + +protected: + bool on_expose_event (GdkEventExpose *); + bool on_button_press_event (GdkEventButton *); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion *); + + bool button_handler (GdkEventButton *); + bool motion_notify_handler (GdkEventMotion *); + bool deliver_event (Duple, GdkEvent *); + +private: + void item_going_away (Item *, boost::optional<Rect>); + bool send_leave_event (Item const *, double, double) const; + + /** the item that the mouse is currently over, or 0 */ + Item const * _current_item; + /** the item that is currently grabbed, or 0 */ + Item const * _grabbed_item; +}; + +/** A GTK::Viewport with a GtkCanvas inside it. This provides a GtkCanvas + * that can be scrolled. + */ +class GtkCanvasViewport : public Gtk::Viewport +{ +public: + GtkCanvasViewport (Gtk::Adjustment &, Gtk::Adjustment &); + + /** @return our GtkCanvas */ + GtkCanvas* canvas () { + return &_canvas; + } + + void window_to_canvas (int, int, Coord &, Coord &) const; + Rect visible_area () const; + +protected: + void on_size_request (Gtk::Requisition *); + +private: + /** our GtkCanvas */ + GtkCanvas _canvas; +}; + +} + +#endif diff --git a/libs/canvas/canvas/debug.h b/libs/canvas/canvas/debug.h new file mode 100644 index 0000000000..ac5f4763ad --- /dev/null +++ b/libs/canvas/canvas/debug.h @@ -0,0 +1,30 @@ +#ifndef __CANVAS_DEBUG_H__ +#define __CANVAS_DEBUG_H__ + +#include <sys/time.h> +#include <map> +#include "pbd/debug.h" + +namespace PBD { + namespace DEBUG { + extern uint64_t CanvasItems; + extern uint64_t CanvasItemsDirtied; + extern uint64_t CanvasEvents; + } +} + +#ifdef CANVAS_DEBUG +#define CANVAS_DEBUG_NAME(i, n) i->name = n; +#else +#define CANVAS_DEBUG(i, n) /* empty */ +#endif + +namespace ArdourCanvas { + extern struct timeval epoch; + extern std::map<std::string, struct timeval> last_time; + extern void checkpoint (std::string, std::string); + extern void set_epoch (); + extern int render_count; +} + +#endif diff --git a/libs/canvas/canvas/fill.h b/libs/canvas/canvas/fill.h new file mode 100644 index 0000000000..0745bae2cc --- /dev/null +++ b/libs/canvas/canvas/fill.h @@ -0,0 +1,35 @@ +#ifndef __CANVAS_FILL_H__ +#define __CANVAS_FILL_H__ + +#include <stdint.h> +#include "canvas/item.h" + +namespace ArdourCanvas { + +class Fill : virtual public Item +{ +public: + Fill (Group *); + + void add_fill_state (XMLNode *) const; + void set_fill_state (XMLNode const *); + + Color fill_color () const { + return _fill_color; + } + void set_fill_color (Color); + bool fill () const { + return _fill; + } + void set_fill (bool); + +protected: + void setup_fill_context (Cairo::RefPtr<Cairo::Context>) const; + + Color _fill_color; + bool _fill; +}; + +} + +#endif diff --git a/libs/canvas/canvas/flag.h b/libs/canvas/canvas/flag.h new file mode 100644 index 0000000000..3127fb09ad --- /dev/null +++ b/libs/canvas/canvas/flag.h @@ -0,0 +1,27 @@ +#include "canvas/group.h" +#include "canvas/types.h" + +namespace ArdourCanvas { + +class Text; +class Line; +class Rectangle; + +class Flag : public Group +{ +public: + Flag (Group *, Distance, Color, Color, Duple); + + void set_text (std::string const &); + void set_height (Distance); + +private: + Distance _height; + Color _outline_color; + Color _fill_color; + Text* _text; + Line* _line; + Rectangle* _rectangle; +}; + +} diff --git a/libs/canvas/canvas/group.h b/libs/canvas/canvas/group.h new file mode 100644 index 0000000000..6a9d59b2b5 --- /dev/null +++ b/libs/canvas/canvas/group.h @@ -0,0 +1,58 @@ +#ifndef __CANVAS_GROUP_H__ +#define __CANVAS_GROUP_H__ + +#include <list> +#include <vector> +#include "canvas/item.h" +#include "canvas/types.h" +#include "canvas/lookup_table.h" + +namespace ArdourCanvas { + +class Group : public Item +{ +public: + explicit Group (Group *); + explicit Group (Group *, Duple); + ~Group (); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + virtual void compute_bounding_box () const; + XMLNode* get_state () const; + void set_state (XMLNode const *); + + void add (Item *); + void remove (Item *); + std::list<Item*> const & items () const { + return _items; + } + + void raise_child_to_top (Item *); + void raise_child (Item *, int); + void lower_child_to_bottom (Item *); + void child_changed (); + + void add_items_at_point (Duple, std::vector<Item const *> &) const; + + static int default_items_per_cell; + +protected: + + explicit Group (Canvas *); + +private: + friend class ::OptimizingLookupTableTest; + + Group (Group const &); + void ensure_lut () const; + void invalidate_lut () const; + + /* our items, from lowest to highest in the stack */ + std::list<Item*> _items; + + mutable LookupTable* _lut; +}; + +} + +#endif diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h new file mode 100644 index 0000000000..bd16fff67d --- /dev/null +++ b/libs/canvas/canvas/item.h @@ -0,0 +1,180 @@ +#ifndef __CANVAS_ITEM_H__ +#define __CANVAS_ITEM_H__ + +#include <stdint.h> + +#include <gdk/gdk.h> + +#include <cairomm/context.h> + +#include "pbd/signals.h" + +#include "canvas/types.h" + +class XMLNode; + +namespace ArdourCanvas +{ + +class Canvas; +class Group; +class Rect; + +/** The parent class for anything that goes on the canvas. + * + * Items have a position, which is expressed in the coordinates of the parent. + * They also have a bounding box, which describes the area in which they have + * drawable content, which is expressed in their own coordinates (whose origin + * is at the item position). + * + * Any item that is being displayed on a canvas has a pointer to that canvas, + * and all except the `root group' have a pointer to their parent group. + */ + +class Item +{ +public: + Item (Canvas *); + Item (Group *); + Item (Group *, Duple); + virtual ~Item (); + + /** Render this item to a Cairo context. + * @param area Area to draw in this item's coordinates. + */ + virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0; + + virtual void add_items_at_point (Duple, std::vector<Item const *>& items) const { + items.push_back (this); + } + + /** Update _bounding_box and _bounding_box_dirty */ + virtual void compute_bounding_box () const = 0; + + virtual XMLNode* get_state () const = 0; + virtual void set_state (XMLNode const *) = 0; + + void grab (); + void ungrab (); + + void add_item_state (XMLNode *) const; + void set_item_state (XMLNode const *); + + void unparent (); + void reparent (Group *); + + /** @return Parent group, or 0 if this is the root group */ + Group* parent () const { + return _parent; + } + + void set_position (Duple); + void set_x_position (Coord); + void set_y_position (Coord); + void move (Duple); + + /** @return Position of this item in the parent's coordinates */ + Duple position () const { + return _position; + } + + boost::optional<Rect> bounding_box () const; + + Duple item_to_parent (Duple const &) const; + Rect item_to_parent (Rect const &) const; + Duple parent_to_item (Duple const &) const; + Rect parent_to_item (Rect const &) const; + /* XXX: it's a pity these aren't the same form as item_to_parent etc., + but it makes a bit of a mess in the rest of the code if they are not. + */ + void canvas_to_item (Coord &, Coord &) const; + void item_to_canvas (Coord &, Coord &) const; + Rect item_to_canvas (Rect const &) const; + + void raise_to_top (); + void raise (int); + void lower_to_bottom (); + + void hide (); + void show (); + + /** @return true if this item is visible (ie it will be rendered), + * otherwise false + */ + bool visible () const { + return _visible; + } + + /** @return Our canvas, or 0 if we are not attached to one */ + Canvas* canvas () const { + return _canvas; + } + + void set_ignore_events (bool); + bool ignore_events () const { + return _ignore_events; + } + + void set_data (std::string const &, void *); + void* get_data (std::string const &) const; + + /* XXX: maybe this should be a PBD::Signal */ + + template <class T> + struct EventAccumulator { + typedef T result_type; + template <class U> + result_type operator () (U first, U last) { + while (first != last) { + if (*first) { + return true; + } + ++first; + } + return false; + } + }; + + sigc::signal<bool, GdkEvent*>::accumulated<EventAccumulator<bool> > Event; + +#ifdef CANVAS_DEBUG + std::string name; +#endif + +#ifdef CANVAS_COMPATIBILITY + void grab_focus (); +#endif + + +protected: + + void begin_change (); + void end_change (); + + Canvas* _canvas; + /** parent group; may be 0 if we are the root group or if we have been unparent()ed */ + Group* _parent; + /** position of this item in parent coordinates */ + Duple _position; + /** true if this item is visible (ie to be drawn), otherwise false */ + bool _visible; + /** our bounding box before any change that is currently in progress */ + boost::optional<Rect> _pre_change_bounding_box; + + /** our bounding box; may be out of date if _bounding_box_dirty is true */ + mutable boost::optional<Rect> _bounding_box; + /** true if _bounding_box might be out of date, false if its definitely not */ + mutable bool _bounding_box_dirty; + + /* XXX: this is a bit grubby */ + std::map<std::string, void *> _data; + +private: + void init (); + + bool _ignore_events; +}; + +} + +#endif diff --git a/libs/canvas/canvas/item_factory.h b/libs/canvas/canvas/item_factory.h new file mode 100644 index 0000000000..149dbaac01 --- /dev/null +++ b/libs/canvas/canvas/item_factory.h @@ -0,0 +1,9 @@ +namespace ArdourCanvas +{ + +class Item; +class Group; + +Item* create_item (Group *, XMLNode const *); + +} diff --git a/libs/canvas/canvas/line.h b/libs/canvas/canvas/line.h new file mode 100644 index 0000000000..85983d55b6 --- /dev/null +++ b/libs/canvas/canvas/line.h @@ -0,0 +1,44 @@ +#ifndef __CANVAS_LINE_H__ +#define __CANVAS_LINE_H__ + +#include "canvas/item.h" +#include "canvas/outline.h" +#include "canvas/poly_line.h" + +namespace ArdourCanvas { + +class Line : virtual public Item, public Outline +{ +public: + Line (Group *); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + XMLNode* get_state () const; + void set_state (XMLNode const *); + + void set (Duple, Duple); + void set_x0 (Coord); + void set_y0 (Coord); + void set_x1 (Coord); + void set_y1 (Coord); + Coord x0 () const { + return _points[0].x; + } + Coord y0 () const { + return _points[0].y; + } + Coord x1 () const { + return _points[1].x; + } + Coord y1 () const { + return _points[1].y; + } + +private: + Duple _points[2]; +}; + +} + +#endif diff --git a/libs/canvas/canvas/line_set.h b/libs/canvas/canvas/line_set.h new file mode 100644 index 0000000000..ec27e6a72e --- /dev/null +++ b/libs/canvas/canvas/line_set.h @@ -0,0 +1,38 @@ +#include "canvas/item.h" + +namespace ArdourCanvas { + +class LineSet : public Item +{ +public: + enum Orientation { + Vertical, + Horizontal + }; + + LineSet (Group *); + + void compute_bounding_box () const; + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + XMLNode* get_state () const; + void set_state (XMLNode const *) {} + + void set_height (Distance); + + void add (Coord, Distance, Color); + void clear (); + + struct Line { + Line (Coord y_, Distance width_, Color color_) : y (y_), width (width_), color (color_) {} + + Coord y; + Distance width; + Color color; + }; + +private: + std::list<Line> _lines; + Distance _height; +}; + +} diff --git a/libs/canvas/canvas/lookup_table.h b/libs/canvas/canvas/lookup_table.h new file mode 100644 index 0000000000..d56394ca58 --- /dev/null +++ b/libs/canvas/canvas/lookup_table.h @@ -0,0 +1,66 @@ +#ifndef __CANVAS_LOOKUP_TABLE_H__ +#define __CANVAS_LOOKUP_TABLE_H__ + +#include <vector> +#include <boost/multi_array.hpp> +#include "canvas/types.h" + +class OptimizingLookupTableTest; + +namespace ArdourCanvas { + +class Item; +class Group; + +class LookupTable +{ +public: + LookupTable (Group const &); + virtual ~LookupTable (); + + virtual std::vector<Item*> get (Rect const &) = 0; + virtual std::vector<Item*> items_at_point (Duple) const = 0; + +protected: + + Group const & _group; +}; + +class DumbLookupTable : public LookupTable +{ +public: + DumbLookupTable (Group const &); + + std::vector<Item*> get (Rect const &); + std::vector<Item*> items_at_point (Duple) const; +}; + +class OptimizingLookupTable : public LookupTable +{ +public: + OptimizingLookupTable (Group const &, int); + ~OptimizingLookupTable (); + std::vector<Item*> get (Rect const &); + std::vector<Item*> items_at_point (Duple) const; + + static int default_items_per_cell; + +private: + + void area_to_indices (Rect const &, int &, int &, int &, int &) const; + void point_to_indices (Duple, int &, int &) const; + + friend class ::OptimizingLookupTableTest; + + typedef std::vector<Item*> Cell; + int _items_per_cell; + int _dimension; + Duple _cell_size; + Duple _offset; + Cell** _cells; + bool _added; +}; + +} + +#endif diff --git a/libs/canvas/canvas/outline.h b/libs/canvas/canvas/outline.h new file mode 100644 index 0000000000..52b1f01061 --- /dev/null +++ b/libs/canvas/canvas/outline.h @@ -0,0 +1,74 @@ +#ifndef __CANVAS_OUTLINE_H__ +#define __CANVAS_OUTLINE_H__ + +#include <stdint.h> +#include "canvas/types.h" +#include "canvas/item.h" + +namespace ArdourCanvas { + +class Outline : virtual public Item +{ +public: + Outline (Group *); + virtual ~Outline () {} + + void add_outline_state (XMLNode *) const; + void set_outline_state (XMLNode const *); + + Color outline_color () const { + return _outline_color; + } + + virtual void set_outline_color (Color); + + Distance outline_width () const { + return _outline_width; + } + + virtual void set_outline_width (Distance); + + bool outline () const { + return _outline; + } + + void set_outline (bool); + +#ifdef CANVAS_COMPATIBILITY + int& property_first_arrowhead () { + return _foo_int; + } + int& property_last_arrowhead () { + return _foo_int; + } + int& property_arrow_shape_a () { + return _foo_int; + } + int& property_arrow_shape_b () { + return _foo_int; + } + int& property_arrow_shape_c () { + return _foo_int; + } + bool& property_draw () { + return _foo_bool; + } +#endif + +protected: + + void setup_outline_context (Cairo::RefPtr<Cairo::Context>) const; + + Color _outline_color; + Distance _outline_width; + bool _outline; + +#ifdef CANVAS_COMPATIBILITY + int _foo_int; + bool _foo_bool; +#endif +}; + +} + +#endif diff --git a/libs/canvas/canvas/pixbuf.h b/libs/canvas/canvas/pixbuf.h new file mode 100644 index 0000000000..31efb1c1ef --- /dev/null +++ b/libs/canvas/canvas/pixbuf.h @@ -0,0 +1,27 @@ +#include <glibmm/refptr.h> + +#include "canvas/item.h" + +namespace Gdk { + class Pixbuf; +} + +namespace ArdourCanvas { + +class Pixbuf : public Item +{ +public: + Pixbuf (Group *); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + XMLNode* get_state () const; + void set_state (XMLNode const *); + + void set (Glib::RefPtr<Gdk::Pixbuf>); + +private: + Glib::RefPtr<Gdk::Pixbuf> _pixbuf; +}; + +} diff --git a/libs/canvas/canvas/poly_item.h b/libs/canvas/canvas/poly_item.h new file mode 100644 index 0000000000..11b649cfb8 --- /dev/null +++ b/libs/canvas/canvas/poly_item.h @@ -0,0 +1,30 @@ +#ifndef __CANVAS_POLY_ITEM_H__ +#define __CANVAS_POLY_ITEM_H__ + +#include "canvas/item.h" +#include "canvas/outline.h" + +namespace ArdourCanvas { + +class PolyItem : virtual public Item, public Outline +{ +public: + PolyItem (Group *); + + void compute_bounding_box () const; + + void add_poly_item_state (XMLNode *) const; + void set_poly_item_state (XMLNode const *); + + void set (Points const &); + Points const & get () const; + +protected: + void render_path (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + + Points _points; +}; + +} + +#endif diff --git a/libs/canvas/canvas/poly_line.h b/libs/canvas/canvas/poly_line.h new file mode 100644 index 0000000000..e870e51876 --- /dev/null +++ b/libs/canvas/canvas/poly_line.h @@ -0,0 +1,21 @@ +#ifndef __CANVAS_POLY_LINE_H__ +#define __CANVAS_POLY_LINE_H__ + +#include "canvas/poly_item.h" +#include "canvas/outline.h" + +namespace ArdourCanvas { + +class PolyLine : public PolyItem +{ +public: + PolyLine (Group *); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + XMLNode* get_state () const; + void set_state (XMLNode const *); +}; + +} + +#endif diff --git a/libs/canvas/canvas/polygon.h b/libs/canvas/canvas/polygon.h new file mode 100644 index 0000000000..3a624d867d --- /dev/null +++ b/libs/canvas/canvas/polygon.h @@ -0,0 +1,22 @@ +#ifndef __CANVAS_POLYGON_H__ +#define __CANVAS_POLYGON_H__ + +#include "canvas/poly_item.h" +#include "canvas/outline.h" +#include "canvas/fill.h" + +namespace ArdourCanvas { + +class Polygon : public PolyItem, public Fill +{ +public: + Polygon (Group *); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + XMLNode* get_state () const; + void set_state (XMLNode const *); +}; + +} + +#endif diff --git a/libs/canvas/canvas/rectangle.h b/libs/canvas/canvas/rectangle.h new file mode 100644 index 0000000000..dd8232c439 --- /dev/null +++ b/libs/canvas/canvas/rectangle.h @@ -0,0 +1,69 @@ +#ifndef __CANVAS_RECTANGLE_H__ +#define __CANVAS_RECTANGLE_H__ + +#include "canvas/item.h" +#include "canvas/types.h" +#include "canvas/outline.h" +#include "canvas/fill.h" + +namespace ArdourCanvas +{ + +class Rectangle : virtual public Item, public Outline, public Fill +{ +public: + Rectangle (Group *); + Rectangle (Group *, Rect const &); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + XMLNode* get_state () const; + void set_state (XMLNode const *); + + Rect const & get () const { + return _rect; + } + + Coord x0 () const { + return _rect.x0; + } + + Coord y0 () const { + return _rect.y0; + } + + Coord x1 () const { + return _rect.x1; + } + + Coord y1 () const { + return _rect.y1; + } + + void set (Rect const &); + void set_x0 (Coord); + void set_y0 (Coord); + void set_x1 (Coord); + void set_y1 (Coord); + + enum What { + LEFT = 0x1, + RIGHT = 0x2, + TOP = 0x4, + BOTTOM = 0x8 + }; + + void set_outline_what (What); + void set_outline_what (int); + +private: + /** Our rectangle; note that x0 may not always be less than x1 + * and likewise with y0 and y1. + */ + Rect _rect; + What _outline_what; +}; + +} + +#endif diff --git a/libs/canvas/canvas/root_group.h b/libs/canvas/canvas/root_group.h new file mode 100644 index 0000000000..bab6d94485 --- /dev/null +++ b/libs/canvas/canvas/root_group.h @@ -0,0 +1,21 @@ +#ifndef __CANVAS_ROOT_GROUP_H__ +#define __CANVAS_ROOT_GROUP_H__ + +#include "group.h" + +namespace ArdourCanvas { + +class RootGroup : public Group +{ +private: + friend class Canvas; + + RootGroup (Canvas *); + + void compute_bounding_box () const; + void child_changed (); +}; + +} + +#endif diff --git a/libs/canvas/canvas/text.h b/libs/canvas/canvas/text.h new file mode 100644 index 0000000000..ccc8d04dd5 --- /dev/null +++ b/libs/canvas/canvas/text.h @@ -0,0 +1,32 @@ +#include <pangomm/fontdescription.h> +#include <pangomm/layout.h> + +#include "canvas/item.h" + +namespace ArdourCanvas { + +class Text : public Item +{ +public: + Text (Group *); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + XMLNode* get_state () const; + void set_state (XMLNode const *); + + void set (std::string const &); + void set_color (uint32_t); + void set_font_description (Pango::FontDescription *); + void set_alignment (Pango::Alignment); + +private: + Glib::RefPtr<Pango::Layout> layout (Cairo::RefPtr<Cairo::Context>) const; + + std::string _text; + Pango::FontDescription* _font_description; + uint32_t _color; + Pango::Alignment _alignment; +}; + +} diff --git a/libs/canvas/canvas/types.h b/libs/canvas/canvas/types.h new file mode 100644 index 0000000000..20b0799ea6 --- /dev/null +++ b/libs/canvas/canvas/types.h @@ -0,0 +1,88 @@ +#ifndef __CANVAS_TYPES_H__ +#define __CANVAS_TYPES_H__ + +#include <iostream> +#include <vector> +#include <stdint.h> +#include <boost/optional.hpp> + +namespace ArdourCanvas +{ + +typedef double Coord; +typedef double Distance; +typedef uint32_t Color; +extern Coord const COORD_MAX; +extern Coord const CAIRO_MAX; + +extern Coord safe_add (Coord, Coord); + +struct Duple +{ + Duple () + : x (0) + , y (0) + {} + + Duple (Coord x_, Coord y_) + : x (x_) + , y (y_) + {} + + Coord x; + Coord y; + + Duple translate (Duple) const; +}; + + +extern Duple operator- (Duple const &); +extern Duple operator+ (Duple const &, Duple const &); +extern Duple operator- (Duple const &, Duple const &); +extern Duple operator/ (Duple const &, double); +extern std::ostream & operator<< (std::ostream &, Duple const &); + +struct Rect +{ + Rect () + : x0 (0) + , y0 (0) + , x1 (0) + , y1 (0) + {} + + Rect (Coord x0_, Coord y0_, Coord x1_, Coord y1_) + : x0 (x0_) + , y0 (y0_) + , x1 (x1_) + , y1 (y1_) + {} + + Coord x0; + Coord y0; + Coord x1; + Coord y1; + + boost::optional<Rect> intersection (Rect const &) const; + Rect extend (Rect const &) const; + Rect translate (Duple) const; + Rect expand (Distance) const; + bool contains (Duple) const; + Rect fix () const; + + Distance width () const { + return x1 - x0; + } + + Distance height () const { + return y1 - y0; + } +}; + +extern std::ostream & operator<< (std::ostream &, Rect const &); + +typedef std::vector<Duple> Points; + +} + +#endif diff --git a/libs/canvas/canvas/utils.h b/libs/canvas/canvas/utils.h new file mode 100644 index 0000000000..8f0e4e868f --- /dev/null +++ b/libs/canvas/canvas/utils.h @@ -0,0 +1,8 @@ +#include "canvas/types.h" + +namespace ArdourCanvas { + +extern void set_source_rgba (Cairo::RefPtr<Cairo::Context>, Color); + +} + diff --git a/libs/canvas/canvas/wave_view.h b/libs/canvas/canvas/wave_view.h new file mode 100644 index 0000000000..8ef0ce9868 --- /dev/null +++ b/libs/canvas/canvas/wave_view.h @@ -0,0 +1,119 @@ +#include <boost/shared_ptr.hpp> +#include "pbd/properties.h" +#include "ardour/types.h" +#include "canvas/item.h" +#include "canvas/fill.h" +#include "canvas/outline.h" + +namespace ARDOUR { + class AudioRegion; +} + +class WaveViewTest; + +namespace ArdourCanvas { + +class WaveView : virtual public Item, public Outline, public Fill +{ +public: + WaveView (Group *, boost::shared_ptr<ARDOUR::AudioRegion>); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + + XMLNode* get_state () const; + void set_state (XMLNode const *); + + void set_frames_per_pixel (double); + void set_height (Distance); + void set_channel (int); + void set_region_start (ARDOUR::frameoffset_t); + + void region_resized (); + + /* XXX */ + void rebuild () {} + +#ifdef CANVAS_COMPATIBILITY + void*& property_gain_src () { + return _foo_void; + } + void*& property_gain_function () { + return _foo_void; + } + bool& property_rectified () { + return _foo_bool; + } + bool& property_logscaled () { + return _foo_bool; + } + double& property_amplitude_above_axis () { + return _foo_double; + } + Color& property_clip_color () { + return _foo_uint; + } + Color& property_zero_color () { + return _foo_uint; + } + +private: + void* _foo_void; + bool _foo_bool; + int _foo_int; + Color _foo_uint; + double _foo_double; +#endif + + class CacheEntry + { + public: + CacheEntry (WaveView const *, int, int); + ~CacheEntry (); + + int start () const { + return _start; + } + + int end () const { + return _end; + } + + ARDOUR::PeakData* peaks () const { + return _peaks; + } + + Glib::RefPtr<Gdk::Pixbuf> pixbuf (); + void clear_pixbuf (); + + private: + Coord position (float) const; + + WaveView const * _wave_view; + int _start; + int _end; + int _n_peaks; + ARDOUR::PeakData* _peaks; + Glib::RefPtr<Gdk::Pixbuf> _pixbuf; + }; + + friend class CacheEntry; + friend class ::WaveViewTest; + + void invalidate_whole_cache (); + void invalidate_pixbuf_cache (); + + boost::shared_ptr<ARDOUR::AudioRegion> _region; + int _channel; + double _frames_per_pixel; + Coord _height; + Color _wave_color; + /** The `start' value to use for the region; we can't use the region's + * value as the crossfade editor needs to alter it. + */ + ARDOUR::frameoffset_t _region_start; + + mutable std::list<CacheEntry*> _cache; +}; + +} |