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;
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());
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();
// 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, -1);

View File

@ -275,6 +275,8 @@ Editor::track_canvas_viewport_size_allocated ()
_visible_canvas_width = _canvas_viewport_allocation.get_width ();
_visible_canvas_height = _canvas_viewport_allocation.get_height ();
cerr << "VISIBLE CANVAS now: " << _visible_canvas_width << " x " << _visible_canvas_height << endl;
if (_session) {
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 */
if (!_internal_editing && get_smart_mode() ) {
double 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 (!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;
if (x >= 0 && y >= 0) {
vector<ArdourCanvas::Item const *> items;
_track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
// first item will be the upper most
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 <gtkmm/adjustment.h>
#include "pbd/xml++.h"
#include "pbd/compose.h"
#include "pbd/stacktrace.h"
#include "canvas/canvas.h"
#include "canvas/debug.h"
@ -74,6 +77,10 @@ Canvas::Canvas (XMLTree const * tree)
void
Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context) const
{
// cerr << "CANVAS @ " << this << endl;
// dump (cerr);
// cerr << "-------------------------\n";
checkpoint ("render", "-> render");
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();
if (!root_bbox) {
/* the root has no bounding box, so there's nothing to render */
checkpoint ("render", "no root bbox");
context->restore ();
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
area, so render it.
*/
checkpoint ("render", "... root");
_root.render (*draw, context);
}
@ -108,6 +117,32 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
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.
* @param item Item that has been shown or hidden.
*/
@ -485,7 +520,7 @@ GtkCanvas::request_size (Duple size)
if (req.y > INT_MAX) {
req.y = INT_MAX;
}
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>
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
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file canvas/canvas.h
@ -92,6 +91,9 @@ public:
_log_renders = log;
}
std::string indent() const;
void dump (std::ostream&) const;
protected:
void queue_draw_item_area (Item *, Rect);
@ -148,7 +150,7 @@ public:
void ungrab ();
Cairo::RefPtr<Cairo::Context> context ();
protected:
bool on_expose_event (GdkEventExpose *);
bool on_button_press_event (GdkEventButton *);
@ -195,4 +197,6 @@ private:
}
std::ostream& operator<< (std::ostream&, const ArdourCanvas::Canvas&);
#endif

View File

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

View File

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

View File

@ -19,6 +19,8 @@ public:
void set (Points const &);
Points const & get () const;
void dump (std::ostream&) const;
protected:
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;
map<string, struct timeval> ArdourCanvas::last_time;
int ArdourCanvas::render_count;
int ArdourCanvas::dump_depth;
void
ArdourCanvas::set_epoch ()

View File

@ -2,16 +2,20 @@
#include <cairomm/context.h>
#include "pbd/stacktrace.h"
#include "pbd/xml++.h"
#include "canvas/group.h"
#include "canvas/types.h"
#include "canvas/debug.h"
#include "canvas/item_factory.h"
#include "canvas/item.h"
#include "canvas/canvas.h"
using namespace std;
using namespace ArdourCanvas;
int Group::default_items_per_cell = 64;
Group::Group (Canvas* canvas)
: Item (canvas)
, _lut (0)
@ -52,11 +56,13 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
vector<Item*> items = _lut->get (area);
for (vector<Item*>::const_iterator i = items.begin(); i != items.end(); ++i) {
if (!(*i)->visible ()) {
continue;
}
boost::optional<Rect> item_bbox = (*i)->bounding_box ();
if (!item_bbox) {
continue;
}
@ -230,3 +236,29 @@ Group::set_state (XMLNode const * node)
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
Item::height () const
{
boost::optional<Rect> bb = bounding_box().get();
return bb->height ();
boost::optional<Rect> bb = bounding_box();
if (bb) {
return bb->height ();
}
return 0;
}
Coord
Item::width () const
{
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 */
@ -325,3 +334,33 @@ Item::set_ignore_events (bool 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 "pbd/xml++.h"
#include "pbd/compose.h"
#include "canvas/poly_item.h"
#include "canvas/canvas.h"
using namespace std;
using namespace ArdourCanvas;
@ -33,6 +36,7 @@ PolyItem::compute_bounding_box () const
}
}
if (!have_one) {
_bounding_box = boost::optional<Rect> ();
} else {
@ -99,3 +103,14 @@ PolyItem::set_poly_item_state (XMLNode const * node)
_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 ();
if (_bounding_box) {
cerr << "!!!!! requesting canvas size " << _bounding_box.get() << endl;
_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
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;
}
@ -135,7 +135,7 @@ ArdourCanvas::operator<< (ostream & s, Duple const & r)
ostream &
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;
}