diff options
Diffstat (limited to 'libs/canvas/canvas')
26 files changed, 2028 insertions, 0 deletions
diff --git a/libs/canvas/canvas/arc.h b/libs/canvas/canvas/arc.h new file mode 100644 index 0000000000..fc1b72163e --- /dev/null +++ b/libs/canvas/canvas/arc.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2013 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_ARC_H__ +#define __CANVAS_ARC_H__ + +#include "canvas/item.h" +#include "canvas/outline.h" +#include "canvas/fill.h" + +namespace ArdourCanvas { + +class Arc : virtual public Item, public Outline, public Fill +{ +public: + Arc (Group *); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + + void set_center (Duple const &); + void set_radius (Coord); + void set_arc (double degrees); + void set_start (double degrees); + + Duple center() const { + return _center; + } + Coord radius () const { + return _radius; + } + double arc_degrees () const { + return _arc_degrees; + } + double start_degrees () const { + return _start_degrees; + } + +private: + Duple _center; + Coord _radius; + double _arc_degrees; + double _start_degrees; +}; + +} + +#endif 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..e65abf6b27 --- /dev/null +++ b/libs/canvas/canvas/canvas.h @@ -0,0 +1,190 @@ +/* + Copyright (C) 2011-2013 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/alignment.h> +#include <cairomm/surface.h> +#include <cairomm/context.h> +#include "pbd/signals.h" +#include "canvas/root_group.h" + +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 (); + 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_visual_property_changed (Item*); + void item_changed (Item *, boost::optional<Rect>); + void item_moved (Item *, boost::optional<Rect>); + + virtual Cairo::RefPtr<Cairo::Context> context () = 0; + + Rect canvas_to_window (Rect const&) const; + Rect window_to_canvas (Rect const&) const; + Duple canvas_to_window (Duple const&) const; + Duple window_to_canvas (Duple const&) const; + + void canvas_to_window (Coord cx, Coord cy, Coord& wx, Coord& wy) { + Duple d = canvas_to_window (Duple (cx, cy)); + wx = d.x; + wy = d.y; + } + + void window_to_canvas (Coord wx, Coord wy, Coord& cx, Coord& cy) { + Duple d = window_to_canvas (Duple (wx, wy)); + cx = d.x; + cy = d.y; + } + + void scroll_to (Coord x, Coord y); + virtual Rect visible_area () const = 0; + + std::string indent() const; + std::string render_indent() const; + void dump (std::ostream&) const; + +protected: + void queue_draw_item_area (Item *, Rect); + + /** our root group */ + RootGroup _root; + + Coord _scroll_offset_x; + Coord _scroll_offset_y; + + virtual void enter_leave_items (int state) = 0; + virtual void enter_leave_items (Duple const &, int state) = 0; +}; + +/** A canvas which renders onto a GTK EventBox */ +class GtkCanvas : public Canvas, public Gtk::EventBox +{ +public: + GtkCanvas (); + + void request_redraw (Rect const &); + void request_size (Duple); + void grab (Item *); + void ungrab (); + + Cairo::RefPtr<Cairo::Context> context (); + + Rect visible_area () const; + +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 *); + + void enter_leave_items (int state); + void enter_leave_items (Duple const &, int state); + +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::Alignment with a GtkCanvas inside it plus some Gtk::Adjustments for + * scrolling. + * + * This provides a GtkCanvas that can be scrolled. It does NOT implement the + * Gtk::Scrollable interface. + */ +class GtkCanvasViewport : public Gtk::Alignment +{ +public: + GtkCanvasViewport (Gtk::Adjustment &, Gtk::Adjustment &); + + /** @return our GtkCanvas */ + GtkCanvas* canvas () { + return &_canvas; + } + +protected: + void on_size_request (Gtk::Requisition *); + +private: + /** our GtkCanvas */ + GtkCanvas _canvas; + Gtk::Adjustment& hadjustment; + Gtk::Adjustment& vadjustment; + + void scrolled (); +}; + +} + +std::ostream& operator<< (std::ostream&, const ArdourCanvas::Canvas&); + +#endif diff --git a/libs/canvas/canvas/circle.h b/libs/canvas/canvas/circle.h new file mode 100644 index 0000000000..030e73312c --- /dev/null +++ b/libs/canvas/canvas/circle.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2013 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_CIRCLE_H__ +#define __CANVAS_CIRCLE_H__ + +#include "canvas/arc.h" + +namespace ArdourCanvas { + +class Circle : public Arc +{ +public: + Circle (Group *); +}; + +} + +#endif diff --git a/libs/canvas/canvas/curve.h b/libs/canvas/canvas/curve.h new file mode 100644 index 0000000000..f2ed6a1d0e --- /dev/null +++ b/libs/canvas/canvas/curve.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2013 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_CURVE_H__ +#define __CANVAS_CURVE_H__ + +#include "canvas/poly_item.h" + +namespace ArdourCanvas { + +class Curve : public PolyItem +{ +public: + Curve (Group *); + + void compute_bounding_box () const; + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + + void set (Points const &); + + protected: + void render_path (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void render_curve (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + + private: + Points first_control_points; + Points second_control_points; + + + static void compute_control_points (Points const &, + Points&, Points&); + static double* solve (std::vector<double> const&); +}; + +} + +#endif diff --git a/libs/canvas/canvas/debug.h b/libs/canvas/canvas/debug.h new file mode 100644 index 0000000000..a025e605dc --- /dev/null +++ b/libs/canvas/canvas/debug.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; + extern uint64_t CanvasRender; + } +} + +#ifdef CANVAS_DEBUG +#define CANVAS_DEBUG_NAME(i, n) i->name = n; +#else +#define CANVAS_DEBUG_NAME(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; + extern int render_depth; + extern int dump_depth; +} + +#endif diff --git a/libs/canvas/canvas/fill.h b/libs/canvas/canvas/fill.h new file mode 100644 index 0000000000..f52260c571 --- /dev/null +++ b/libs/canvas/canvas/fill.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#ifndef __CANVAS_FILL_H__ +#define __CANVAS_FILL_H__ + +#include <vector> +#include <stdint.h> +#include "canvas/item.h" + +namespace ArdourCanvas { + +class Fill : virtual public Item +{ +public: + Fill (Group *); + + virtual void set_fill_color (Color); + virtual void set_fill (bool); + + Color fill_color () const { + return _fill_color; + } + + bool fill () const { + return _fill; + } + + typedef std::vector<std::pair<double,Color> > StopList; + + void set_gradient (StopList const & stops, bool is_vertical); + +protected: + void setup_fill_context (Cairo::RefPtr<Cairo::Context>) const; + void setup_gradient_context (Cairo::RefPtr<Cairo::Context>, Rect const &, Duple const &) const; + + Color _fill_color; + bool _fill; + StopList _stops; + bool _vertical_gradient; +}; + +} + +#endif diff --git a/libs/canvas/canvas/flag.h b/libs/canvas/canvas/flag.h new file mode 100644 index 0000000000..6664524a19 --- /dev/null +++ b/libs/canvas/canvas/flag.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2011-2013 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 "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/fwd.h b/libs/canvas/canvas/fwd.h new file mode 100644 index 0000000000..1e812f9144 --- /dev/null +++ b/libs/canvas/canvas/fwd.h @@ -0,0 +1,36 @@ +/* + 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. + +*/ + +#ifndef __canvas_canvas_fwd_h__ +#define __canvas_canvas_fwd_h__ + +namespace ArdourCanvas { + class WaveView; + class Line; + class Rectangle; + class Polygon; + class PolyLine; + class GtkCanvas; + class GtkCanvasViewport; + class Text; + class Curve; +} + +#endif /* __canvas_canvas_fwd_h__ */ diff --git a/libs/canvas/canvas/group.h b/libs/canvas/canvas/group.h new file mode 100644 index 0000000000..9a72d50873 --- /dev/null +++ b/libs/canvas/canvas/group.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; + + void add (Item *); + void remove (Item *); + void clear (bool with_delete = false); + 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; + + void dump (std::ostream&) 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/image.h b/libs/canvas/canvas/image.h new file mode 100644 index 0000000000..0dcf8e51b3 --- /dev/null +++ b/libs/canvas/canvas/image.h @@ -0,0 +1,110 @@ +/* + Copyright (C) 2013 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_IMAGE__ +#define __CANVAS_IMAGE__ + +#include <stdint.h> +#include <boost/shared_ptr.hpp> +#include <boost/shared_array.hpp> + +#include "canvas/item.h" + +typedef void (*ImageReleaseCallback)(uint8_t *d, void *arg); + +namespace ArdourCanvas { + + +class Image : public Item +{ +public: + Image (Group *, Cairo::Format, int width, int height); + + struct Data { + Data (uint8_t *d, int w, int h, int s, Cairo::Format fmt) + : data (d) + , width (w) + , height (h) + , stride (s) + , format (fmt) + , destroy_callback(NULL) + , destroy_arg(NULL) + {} + + virtual ~Data () { + if (destroy_callback) { + destroy_callback(data, destroy_arg); + } else { + free(data); + } + } + + uint8_t* data; + int width; + int height; + int stride; + Cairo::Format format; + ImageReleaseCallback destroy_callback; + void* destroy_arg; + }; + + /** + * Returns a shared_ptr to a Data object that can be used to + * write image data to. The Data object will contain a pointer + * to the buffer, along with image properties that may be + * useful during the data writing. + * + * Can be called from any thread BUT .. + * + * ... to avoid collisions with Image deletion, some synchronization method + * may be required or the use of shared_ptr<Image> or similar. + */ + boost::shared_ptr<Data> get_image (bool allocate_data = true); + + + /** + * Queues a Data object to be used to redraw this Image item + * at the earliest possible opportunity. + * + * May be called from any thread BUT ... + * + * ... to avoid collisions with Image deletion, some synchronization method + * may be required or the use of shared_ptr<Image> or similar. + */ + void put_image (boost::shared_ptr<Data>); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + +private: + Cairo::Format _format; + int _width; + int _height; + int _data; + mutable boost::shared_ptr<Data> _current; + boost::shared_ptr<Data> _pending; + mutable bool _need_render; + mutable Cairo::RefPtr<Cairo::Surface> _surface; + + void accept_data (); + PBD::Signal0<void> DataReady; + PBD::ScopedConnectionList data_connections; +}; + +} +#endif diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h new file mode 100644 index 0000000000..e856c7e149 --- /dev/null +++ b/libs/canvas/canvas/item.h @@ -0,0 +1,230 @@ +/* + Copyright (C) 2011-2013 Paul Davis + Original 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. +*/ + +#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" + +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 **window** coordinates + * + * Items must convert their own coordinates into window coordinates + * because Cairo is limited to a fixed point coordinate space that + * does not extend as far as the Ardour timeline. All rendering must + * be done using coordinates that do not exceed the (rough) limits + * of the canvas' window, to avoid odd errors within Cairo as it + * converts doubles into its fixed point format and then tesselates + * the results. + */ + 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; + + void grab (); + void ungrab (); + + 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; + Coord height() const; + Coord width() 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; + Duple canvas_to_item (Duple const &) const; + void item_to_canvas (Coord &, Coord &) const; + Rect item_to_canvas (Rect const &) const; + Rect canvas_to_item (Rect const &) const; + Duple item_to_canvas (Duple const &) const; + + Duple item_to_window (Duple const&) const; + Duple window_to_item (Duple const&) const; + Rect item_to_window (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; + + /* This is a sigc++ signal because it is solely + concerned with GUI stuff and is thus single-threaded + */ + + 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::signal1<bool, GdkEvent*, EventAccumulator<bool> > Event; + +#ifdef CANVAS_DEBUG + std::string name; +#endif + +#ifdef CANVAS_COMPATIBILITY + void grab_focus (); +#endif + + virtual void dump (std::ostream&) const; + std::string whatami() const; + +protected: + + /** To be called at the beginning of any property change that + * may alter the bounding box of this item + */ + void begin_change (); + /** To be called at the endof any property change that + * may alter the bounding box of this item + */ + void end_change (); + /** To be called at the beginning of any property change that + * does NOT alter the bounding box of this item + */ + void begin_visual_change (); + /** To be called at the endof any property change that + * does NOT alter the bounding box of this item + */ + void end_visual_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; +}; + +extern std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&); + +} + + +#endif diff --git a/libs/canvas/canvas/line.h b/libs/canvas/canvas/line.h new file mode 100644 index 0000000000..36c0f48379 --- /dev/null +++ b/libs/canvas/canvas/line.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; + + void set (Duple, Duple); + void set_x0 (Coord); + void set_y0 (Coord); + void set_x1 (Coord); + void set_y1 (Coord); + void set_x (Coord, 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..cd551438b1 --- /dev/null +++ b/libs/canvas/canvas/line_set.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2011-2013 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 "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; + + 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..4ab69b6167 --- /dev/null +++ b/libs/canvas/canvas/lookup_table.h @@ -0,0 +1,85 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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..c315da874c --- /dev/null +++ b/libs/canvas/canvas/outline.h @@ -0,0 +1,90 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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 () {} + + 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; + } + + virtual 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..ed1be5fe5c --- /dev/null +++ b/libs/canvas/canvas/pixbuf.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#ifndef __CANVAS_PIXBUF__ +#define __CANVAS_PIXBUF__ + +#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; + + void set (Glib::RefPtr<Gdk::Pixbuf>); + + /* returns the reference to the internal private pixbuf + * after changing data in the pixbuf a call to set() + * is mandatory to update the data on screen */ + Glib::RefPtr<Gdk::Pixbuf> pixbuf(); + +private: + Glib::RefPtr<Gdk::Pixbuf> _pixbuf; +}; + +} +#endif diff --git a/libs/canvas/canvas/poly_item.h b/libs/canvas/canvas/poly_item.h new file mode 100644 index 0000000000..10e41e9ca6 --- /dev/null +++ b/libs/canvas/canvas/poly_item.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; + + virtual void set (Points const &); + Points const & get () const; + + void dump (std::ostream&) const; + +protected: + void render_path (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void render_curve (Rect const &, Cairo::RefPtr<Cairo::Context>, Points const &, Points const &) 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..911dd140fc --- /dev/null +++ b/libs/canvas/canvas/poly_line.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; +}; + +} + +#endif diff --git a/libs/canvas/canvas/polygon.h b/libs/canvas/canvas/polygon.h new file mode 100644 index 0000000000..addfe48100 --- /dev/null +++ b/libs/canvas/canvas/polygon.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; +}; + +} + +#endif diff --git a/libs/canvas/canvas/rectangle.h b/libs/canvas/canvas/rectangle.h new file mode 100644 index 0000000000..f93324b39e --- /dev/null +++ b/libs/canvas/canvas/rectangle.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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; + + 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..74cfbac29f --- /dev/null +++ b/libs/canvas/canvas/root_group.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#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..6ae6d58a37 --- /dev/null +++ b/libs/canvas/canvas/text.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#ifndef __ardour_canvas_text_h__ +#define __ardour_canvas_text_h__ + +#include <pangomm/fontdescription.h> +#include <pangomm/layout.h> + +#include "canvas/item.h" + +namespace ArdourCanvas { + +class Text : public Item +{ +public: + Text (Group *); + ~Text(); + + void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + + void set (std::string const &); + void set_color (uint32_t); + void set_font_description (Pango::FontDescription); + void set_alignment (Pango::Alignment); + + void clamp_width (double); + + void set_size_chars (int nchars); + void dump (std::ostream&) const; + +private: + std::string _text; + uint32_t _color; + Pango::FontDescription* _font_description; + Pango::Alignment _alignment; + mutable Cairo::RefPtr<Cairo::ImageSurface> _image; + mutable Duple _origin; + mutable double _width; + mutable double _height; + mutable bool _need_redraw; + double _clamped_width; + + void redraw (Cairo::RefPtr<Cairo::Context>) const; +}; + +} + +#endif /* __ardour_canvas_text_h__ */ diff --git a/libs/canvas/canvas/types.h b/libs/canvas/canvas/types.h new file mode 100644 index 0000000000..33bb92ca58 --- /dev/null +++ b/libs/canvas/canvas/types.h @@ -0,0 +1,115 @@ +/* + Copyright (C) 2011-2013 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. +*/ + +#ifndef __CANVAS_TYPES_H__ +#define __CANVAS_TYPES_H__ + +#include <iostream> +#include <vector> +#include <stdint.h> +#include <boost/optional.hpp> + +#include <cairomm/refptr.h> + +namespace Cairo { + struct Context; +} + +namespace ArdourCanvas +{ + +typedef double Coord; +typedef double Distance; +typedef uint32_t Color; + +extern Coord const COORD_MAX; + +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 bool 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; + + Rect convert_to_device (Cairo::RefPtr<Cairo::Context>) const; + Rect convert_to_user (Cairo::RefPtr<Cairo::Context>) 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..9db677b61b --- /dev/null +++ b/libs/canvas/canvas/utils.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2011-2013 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 "canvas/types.h" + +namespace ArdourCanvas { + + extern void color_to_hsv (Color color, double& h, double& s, double& v); + extern Color hsv_to_color (double h, double s, double v, double a); + + extern void color_to_rgba (Color, double& r, double& g, double& b, double& a); + extern Color rgba_to_color (double r, double g, double b, double a); + + 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..fc39d7e555 --- /dev/null +++ b/libs/canvas/canvas/wave_view.h @@ -0,0 +1,176 @@ +/* + Copyright (C) 2011-2013 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 <boost/shared_ptr.hpp> +#include <boost/shared_array.hpp> +#include <boost/scoped_array.hpp> + +#include "pbd/properties.h" + +#include "ardour/types.h" + +#include <glibmm/refptr.h> + +#include "canvas/item.h" +#include "canvas/fill.h" +#include "canvas/outline.h" + +namespace ARDOUR { + class AudioRegion; +} + +namespace Gdk { + class Pixbuf; +} + +class WaveViewTest; + +namespace ArdourCanvas { + +class WaveView : virtual public Item, public Outline, public Fill +{ +public: + enum Shape { + Normal, + Rectified, + }; + + /* Displays a single channel of waveform data for the given Region. + + x = 0 in the waveview corresponds to the first waveform datum taken + from region->start() samples into the source data. + + x = N in the waveview corresponds to the (N * spp)'th sample + measured from region->start() into the source data. + + when drawing, we will map the zeroth-pixel of the waveview + into a window. + + The waveview itself contains a set of pre-rendered Cairo::ImageSurfaces + that cache sections of the display. This is filled on-demand and + never cleared until something explicitly marks the cache invalid + (such as a change in samples_per_pixel, the log scaling, rectified or + other view parameters). + */ + + + WaveView (Group *, boost::shared_ptr<ARDOUR::AudioRegion>); + ~WaveView (); + + void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const; + void compute_bounding_box () const; + + void set_samples_per_pixel (double); + void set_height (Distance); + void set_channel (int); + void set_region_start (ARDOUR::frameoffset_t); + + void set_fill_color (Color); + void set_outline_color (Color); + + void region_resized (); + void gain_changed (); + + void set_show_zero_line (bool); + bool show_zero_line() const { return _show_zero; } + void set_zero_color (Color); + void set_clip_color (Color); + void set_logscaled (bool); + void set_gradient_depth (double); + double gradient_depth() const { return _gradient_depth; } + void set_shape (Shape); + + + /* currently missing because we don't need them (yet): + set_shape_independent(); + set_logscaled_independent() + */ + + static void set_global_gradient_depth (double); + static void set_global_logscaled (bool); + static void set_global_shape (Shape); + static void set_global_show_waveform_clipping (bool); + + static double global_gradient_depth() { return _global_gradient_depth; } + static bool global_logscaled() { return _global_logscaled; } + static Shape global_shape() { return _global_shape; } + + void set_amplitude_above_axis (double v); + double amplitude_above_axis () const { return _amplitude_above_axis; } + +#ifdef CANVAS_COMPATIBILITY + void*& property_gain_src () { + return _foo_void; + } + void*& property_gain_function () { + return _foo_void; + } +private: + void* _foo_void; + +#endif + + friend class ::WaveViewTest; + + void invalidate_image (); + + boost::shared_ptr<ARDOUR::AudioRegion> _region; + int _channel; + double _samples_per_pixel; + Coord _height; + Color _wave_color; + bool _show_zero; + Color _zero_color; + Color _clip_color; + bool _logscaled; + Shape _shape; + double _gradient_depth; + bool _shape_independent; + bool _logscaled_independent; + bool _gradient_depth_independent; + double _amplitude_above_axis; + + /** 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 ARDOUR::framepos_t _sample_start; + mutable ARDOUR::framepos_t _sample_end; + mutable Cairo::RefPtr<Cairo::ImageSurface> _image; + + PBD::ScopedConnection invalidation_connection; + + static double _global_gradient_depth; + static bool _global_logscaled; + static Shape _global_shape; + static bool _global_show_waveform_clipping; + + static PBD::Signal0<void> VisualPropertiesChanged; + + void handle_visual_property_change (); + + void ensure_cache (ARDOUR::framepos_t sample_start, ARDOUR::framepos_t sample_end) const; + ArdourCanvas::Coord position (double) const; + void draw_image (ARDOUR::PeakData*, int npeaks) const; +}; + +} |