lots of tweaking and adding debug output including operator<</dump(ostream&) methods to help visualize canvas structure

This commit is contained in:
Paul Davis 2013-04-05 11:27:26 -04:00
parent 7db5d68cdb
commit 07a505b1b2
15 changed files with 188 additions and 23 deletions

View file

@ -496,7 +496,7 @@ Editor::Editor ()
_cursors = new MouseCursors; _cursors = new MouseCursors;
ArdourCanvas::Canvas* time_pad = new ArdourCanvas::GtkCanvas (); ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root()); ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root());
pad_line_1->set (ArdourCanvas::Duple (0.0, 1.0), ArdourCanvas::Duple (100.0, 1.0)); pad_line_1->set (ArdourCanvas::Duple (0.0, 1.0), ArdourCanvas::Duple (100.0, 1.0));
@ -504,7 +504,7 @@ Editor::Editor ()
pad_line_1->show(); pad_line_1->show();
// CAIROCANVAS // CAIROCANVAS
//time_pad->show(); time_pad->show();
time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2); time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2);
time_canvas_vbox.set_size_request (-1, -1); time_canvas_vbox.set_size_request (-1, -1);

View file

@ -275,6 +275,8 @@ Editor::track_canvas_viewport_size_allocated ()
_visible_canvas_width = _canvas_viewport_allocation.get_width (); _visible_canvas_width = _canvas_viewport_allocation.get_width ();
_visible_canvas_height = _canvas_viewport_allocation.get_height (); _visible_canvas_height = _canvas_viewport_allocation.get_height ();
cerr << "VISIBLE CANVAS now: " << _visible_canvas_width << " x " << _visible_canvas_height << endl;
if (_session) { if (_session) {
TrackViewList::iterator i; TrackViewList::iterator i;

View file

@ -308,19 +308,26 @@ Editor::set_canvas_cursor ()
/* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */ /* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */
if (!_internal_editing && get_smart_mode() ) { if (!_internal_editing && get_smart_mode() ) {
double x, y; double x, y;
get_pointer_position (x, y); get_pointer_position (x, y);
vector<ArdourCanvas::Item const *> items;
_track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
// CAIROCANVAS: need upper-most item, not all items if (x >= 0 && y >= 0) {
if (!items.empty()) { vector<ArdourCanvas::Item const *> items;
const ArdourCanvas::Item* i = items.front();
if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) { _track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y + vertical_adjustment.get_value());
if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) { // first item will be the upper most
current_canvas_cursor = _cursors->up_down;
if (!items.empty()) {
const ArdourCanvas::Item* i = items.front();
if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) {
pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y + vertical_adjustment.get_value());
if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
current_canvas_cursor = _cursors->up_down;
}
} }
} }
} }

View file

@ -24,8 +24,11 @@
#include <cassert> #include <cassert>
#include <gtkmm/adjustment.h> #include <gtkmm/adjustment.h>
#include "pbd/xml++.h" #include "pbd/xml++.h"
#include "pbd/compose.h" #include "pbd/compose.h"
#include "pbd/stacktrace.h"
#include "canvas/canvas.h" #include "canvas/canvas.h"
#include "canvas/debug.h" #include "canvas/debug.h"
@ -74,6 +77,10 @@ Canvas::Canvas (XMLTree const * tree)
void void
Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context) const Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context) const
{ {
// cerr << "CANVAS @ " << this << endl;
// dump (cerr);
// cerr << "-------------------------\n";
checkpoint ("render", "-> render"); checkpoint ("render", "-> render");
render_count = 0; render_count = 0;
@ -86,6 +93,7 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
boost::optional<Rect> root_bbox = _root.bounding_box(); boost::optional<Rect> root_bbox = _root.bounding_box();
if (!root_bbox) { if (!root_bbox) {
/* the root has no bounding box, so there's nothing to render */ /* the root has no bounding box, so there's nothing to render */
checkpoint ("render", "no root bbox");
context->restore (); context->restore ();
return; return;
} }
@ -95,6 +103,7 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
/* there's a common area between the root and the requested /* there's a common area between the root and the requested
area, so render it. area, so render it.
*/ */
checkpoint ("render", "... root");
_root.render (*draw, context); _root.render (*draw, context);
} }
@ -108,6 +117,32 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
checkpoint ("render", "<- render"); checkpoint ("render", "<- render");
} }
ostream&
operator<< (ostream& o, Canvas& c)
{
c.dump (o);
return o;
}
std::string
Canvas::indent() const
{
string s;
for (int n = 0; n < ArdourCanvas::dump_depth; ++n) {
s += '\t';
}
return s;
}
void
Canvas::dump (ostream& o) const
{
dump_depth = 0;
_root.dump (o);
}
/** Called when an item has been shown or hidden. /** Called when an item has been shown or hidden.
* @param item Item that has been shown or hidden. * @param item Item that has been shown or hidden.
*/ */
@ -485,7 +520,7 @@ GtkCanvas::request_size (Duple size)
if (req.y > INT_MAX) { if (req.y > INT_MAX) {
req.y = INT_MAX; req.y = INT_MAX;
} }
set_size_request (req.x, req.y); set_size_request (req.x, req.y);
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2011 Paul Davis Copyright (C) 2011-2013 Paul Davis
Author: Carl Hetherington <cth@carlh.net> Author: Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@ -15,7 +15,6 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/** @file canvas/canvas.h /** @file canvas/canvas.h
@ -92,6 +91,9 @@ public:
_log_renders = log; _log_renders = log;
} }
std::string indent() const;
void dump (std::ostream&) const;
protected: protected:
void queue_draw_item_area (Item *, Rect); void queue_draw_item_area (Item *, Rect);
@ -148,7 +150,7 @@ public:
void ungrab (); void ungrab ();
Cairo::RefPtr<Cairo::Context> context (); Cairo::RefPtr<Cairo::Context> context ();
protected: protected:
bool on_expose_event (GdkEventExpose *); bool on_expose_event (GdkEventExpose *);
bool on_button_press_event (GdkEventButton *); bool on_button_press_event (GdkEventButton *);
@ -195,4 +197,6 @@ private:
} }
std::ostream& operator<< (std::ostream&, const ArdourCanvas::Canvas&);
#endif #endif

View file

@ -25,6 +25,7 @@ namespace ArdourCanvas {
extern void checkpoint (std::string, std::string); extern void checkpoint (std::string, std::string);
extern void set_epoch (); extern void set_epoch ();
extern int render_count; extern int render_count;
extern int dump_depth;
} }
#endif #endif

View file

@ -34,6 +34,8 @@ public:
void add_items_at_point (Duple, std::vector<Item const *> &) const; void add_items_at_point (Duple, std::vector<Item const *> &) const;
void dump (std::ostream&) const;
static int default_items_per_cell; static int default_items_per_cell;
protected: protected:

View file

@ -1,3 +1,22 @@
/*
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__ #ifndef __CANVAS_ITEM_H__
#define __CANVAS_ITEM_H__ #define __CANVAS_ITEM_H__
@ -148,8 +167,10 @@ public:
#ifdef CANVAS_COMPATIBILITY #ifdef CANVAS_COMPATIBILITY
void grab_focus (); void grab_focus ();
#endif #endif
virtual void dump (std::ostream&) const;
std::string whatami() const;
protected: protected:
void begin_change (); void begin_change ();
@ -179,6 +200,9 @@ private:
bool _ignore_events; bool _ignore_events;
}; };
extern std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
} }
#endif #endif

View file

@ -19,6 +19,8 @@ public:
void set (Points const &); void set (Points const &);
Points const & get () const; Points const & get () const;
void dump (std::ostream&) const;
protected: protected:
void render_path (Rect const &, Cairo::RefPtr<Cairo::Context>) const; void render_path (Rect const &, Cairo::RefPtr<Cairo::Context>) const;

View file

@ -11,6 +11,7 @@ uint64_t PBD::DEBUG::CanvasEvents = PBD::new_debug_bit ("canvasevents");
struct timeval ArdourCanvas::epoch; struct timeval ArdourCanvas::epoch;
map<string, struct timeval> ArdourCanvas::last_time; map<string, struct timeval> ArdourCanvas::last_time;
int ArdourCanvas::render_count; int ArdourCanvas::render_count;
int ArdourCanvas::dump_depth;
void void
ArdourCanvas::set_epoch () ArdourCanvas::set_epoch ()

View file

@ -2,16 +2,20 @@
#include <cairomm/context.h> #include <cairomm/context.h>
#include "pbd/stacktrace.h" #include "pbd/stacktrace.h"
#include "pbd/xml++.h" #include "pbd/xml++.h"
#include "canvas/group.h" #include "canvas/group.h"
#include "canvas/types.h" #include "canvas/types.h"
#include "canvas/debug.h" #include "canvas/debug.h"
#include "canvas/item_factory.h" #include "canvas/item_factory.h"
#include "canvas/item.h"
#include "canvas/canvas.h"
using namespace std; using namespace std;
using namespace ArdourCanvas; using namespace ArdourCanvas;
int Group::default_items_per_cell = 64; int Group::default_items_per_cell = 64;
Group::Group (Canvas* canvas) Group::Group (Canvas* canvas)
: Item (canvas) : Item (canvas)
, _lut (0) , _lut (0)
@ -52,11 +56,13 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
vector<Item*> items = _lut->get (area); vector<Item*> items = _lut->get (area);
for (vector<Item*>::const_iterator i = items.begin(); i != items.end(); ++i) { for (vector<Item*>::const_iterator i = items.begin(); i != items.end(); ++i) {
if (!(*i)->visible ()) { if (!(*i)->visible ()) {
continue; continue;
} }
boost::optional<Rect> item_bbox = (*i)->bounding_box (); boost::optional<Rect> item_bbox = (*i)->bounding_box ();
if (!item_bbox) { if (!item_bbox) {
continue; continue;
} }
@ -230,3 +236,29 @@ Group::set_state (XMLNode const * node)
create_item (this, *i); create_item (this, *i);
} }
} }
void
Group::dump (ostream& o) const
{
o << _canvas->indent();
o << "Group " << this;
o << " Items: " << _items.size();
boost::optional<Rect> bb = bounding_box();
if (bb) {
o << endl << _canvas->indent() << " bbox: " << bb.get();
} else {
o << " bbox unset";
}
o << endl;
ArdourCanvas::dump_depth++;
for (list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
o << **i;
}
ArdourCanvas::dump_depth--;
}

View file

@ -195,15 +195,24 @@ Item::bounding_box () const
Coord Coord
Item::height () const Item::height () const
{ {
boost::optional<Rect> bb = bounding_box().get(); boost::optional<Rect> bb = bounding_box();
return bb->height ();
if (bb) {
return bb->height ();
}
return 0;
} }
Coord Coord
Item::width () const Item::width () const
{ {
boost::optional<Rect> bb = bounding_box().get(); boost::optional<Rect> bb = bounding_box().get();
return bb->width ();
if (bb) {
return bb->width ();
}
return 0;
} }
/* XXX may be called even if bbox is not changing ... bit grotty */ /* XXX may be called even if bbox is not changing ... bit grotty */
@ -325,3 +334,33 @@ Item::set_ignore_events (bool ignore)
{ {
_ignore_events = ignore; _ignore_events = ignore;
} }
void
Item::dump (ostream& o) const
{
boost::optional<Rect> bb = bounding_box();
o << _canvas->indent() << whatami() << ' ' << this;
if (bb) {
o << endl << _canvas->indent() << "\tbbox: " << bb.get();
} else {
o << "bbox unset";
}
o << endl;
}
std::string
Item::whatami () const
{
std::string type = demangle (typeid (*this).name());
return type.substr (type.find_last_of (':') + 1);
}
ostream&
ArdourCanvas::operator<< (ostream& o, const Item& i)
{
i.dump (o);
return o;
}

View file

@ -1,7 +1,10 @@
#include <algorithm> #include <algorithm>
#include "pbd/xml++.h" #include "pbd/xml++.h"
#include "pbd/compose.h" #include "pbd/compose.h"
#include "canvas/poly_item.h" #include "canvas/poly_item.h"
#include "canvas/canvas.h"
using namespace std; using namespace std;
using namespace ArdourCanvas; using namespace ArdourCanvas;
@ -33,6 +36,7 @@ PolyItem::compute_bounding_box () const
} }
} }
if (!have_one) { if (!have_one) {
_bounding_box = boost::optional<Rect> (); _bounding_box = boost::optional<Rect> ();
} else { } else {
@ -99,3 +103,14 @@ PolyItem::set_poly_item_state (XMLNode const * node)
_bounding_box_dirty = true; _bounding_box_dirty = true;
} }
void
PolyItem::dump (ostream& o) const
{
Item::dump (o);
o << _canvas->indent() << _points.size() << " points" << endl;
for (Points::const_iterator i = _points.begin(); i != _points.end(); ++i) {
o << i->x << ", " << i->y << endl;
}
}

View file

@ -18,6 +18,7 @@ RootGroup::compute_bounding_box () const
Group::compute_bounding_box (); Group::compute_bounding_box ();
if (_bounding_box) { if (_bounding_box) {
cerr << "!!!!! requesting canvas size " << _bounding_box.get() << endl;
_canvas->request_size (Duple (_bounding_box.get().width (), _bounding_box.get().height ())); _canvas->request_size (Duple (_bounding_box.get().width (), _bounding_box.get().height ()));
} }
} }

View file

@ -13,7 +13,7 @@ Coord const ArdourCanvas::CAIRO_MAX = 65536;
static inline Coord static inline Coord
safe_add (Coord a, Coord b) safe_add (Coord a, Coord b)
{ {
if (((COORD_MAX - a) > b) || ((COORD_MAX - b) > a)) { if (((COORD_MAX - a) <= b) || ((COORD_MAX - b) <= a)) {
return COORD_MAX; return COORD_MAX;
} }
@ -135,7 +135,7 @@ ArdourCanvas::operator<< (ostream & s, Duple const & r)
ostream & ostream &
ArdourCanvas::operator<< (ostream & s, Rect const & r) ArdourCanvas::operator<< (ostream & s, Rect const & r)
{ {
s << "[(" << r.x0 << ", " << r.y0 << "), (" << r.x1 << ", " << r.y1 << ")]"; s << "[(" << r.x0 << ", " << r.y0 << "), (" << r.x1 << ", " << r.y1 << ") " << r.width() << " x " << r.height() << "]";
return s; return s;
} }