Add an optional ArdourCanvas::Item::prepare_for_render interface
Called when an item has requested a redraw and intersects with visible canvas area. Also add Canvas::prepare_for_render that will call Item::prepare_for_render for items visible on the canvas.
This commit is contained in:
parent
265f52535a
commit
c4e31fc322
@ -144,6 +144,22 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Canvas::prepare_for_render (Rect const & area) const
|
||||||
|
{
|
||||||
|
Rect root_bbox = _root.bounding_box();
|
||||||
|
if (!root_bbox) {
|
||||||
|
/* the root has no bounding box, so there's nothing to render */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect draw = root_bbox.intersection (area);
|
||||||
|
|
||||||
|
if (draw) {
|
||||||
|
_root.prepare_for_render (draw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ostream&
|
ostream&
|
||||||
operator<< (ostream& o, Canvas& c)
|
operator<< (ostream& o, Canvas& c)
|
||||||
{
|
{
|
||||||
@ -231,9 +247,17 @@ Canvas::item_changed (Item* item, Rect pre_change_bounding_box)
|
|||||||
Rect post_change_bounding_box = item->bounding_box ();
|
Rect post_change_bounding_box = item->bounding_box ();
|
||||||
|
|
||||||
if (post_change_bounding_box) {
|
if (post_change_bounding_box) {
|
||||||
if (item->item_to_window (post_change_bounding_box).intersection (window_bbox)) {
|
Rect const window_intersection =
|
||||||
|
item->item_to_window (post_change_bounding_box).intersection (window_bbox);
|
||||||
|
|
||||||
|
if (window_intersection) {
|
||||||
/* request a redraw of the item's new bounding box */
|
/* request a redraw of the item's new bounding box */
|
||||||
queue_draw_item_area (item, post_change_bounding_box);
|
queue_draw_item_area (item, post_change_bounding_box);
|
||||||
|
|
||||||
|
// Allow item to do any work necessary to prepare for being rendered.
|
||||||
|
item->prepare_for_render (window_intersection);
|
||||||
|
} else {
|
||||||
|
// No intersection with visible window area
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -937,6 +961,13 @@ GtkCanvas::on_expose_event (GdkEventExpose* ev)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GtkCanvas::prepare_for_render () const
|
||||||
|
{
|
||||||
|
Rect window_bbox = visible_area ();
|
||||||
|
Canvas::prepare_for_render (window_bbox);
|
||||||
|
}
|
||||||
|
|
||||||
/** Handler for GDK scroll events.
|
/** Handler for GDK scroll events.
|
||||||
* @param ev Event.
|
* @param ev Event.
|
||||||
* @return true if the event was handled.
|
* @return true if the event was handled.
|
||||||
|
@ -87,6 +87,8 @@ public:
|
|||||||
|
|
||||||
void render (Rect const &, Cairo::RefPtr<Cairo::Context> const &) const;
|
void render (Rect const &, Cairo::RefPtr<Cairo::Context> const &) const;
|
||||||
|
|
||||||
|
void prepare_for_render (Rect const &) const;
|
||||||
|
|
||||||
/** @return root group */
|
/** @return root group */
|
||||||
Item* root () {
|
Item* root () {
|
||||||
return &_root;
|
return &_root;
|
||||||
@ -214,6 +216,8 @@ public:
|
|||||||
Canvas::render (rect, ctx);
|
Canvas::render (rect, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prepare_for_render () const;
|
||||||
|
|
||||||
uint32_t background_color() { return Canvas::background_color (); }
|
uint32_t background_color() { return Canvas::background_color (); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -53,6 +53,12 @@ public:
|
|||||||
* (just call Item::render_children()). It can be overridden as necessary.
|
* (just call Item::render_children()). It can be overridden as necessary.
|
||||||
*/
|
*/
|
||||||
void render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
|
void render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
|
||||||
|
|
||||||
|
/** The prepare_for_render() method is likely to be identical in all
|
||||||
|
* containers (just call Item::prepare_for_render_children()). It can be
|
||||||
|
* overridden as necessary.
|
||||||
|
*/
|
||||||
|
void prepare_for_render (Rect const & area) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0;
|
virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0;
|
||||||
|
|
||||||
|
/** Item has changed will be rendered in next render pass so give item a
|
||||||
|
* chance to perhaps schedule work in another thread etc.
|
||||||
|
*
|
||||||
|
* @param area Area to draw, in **window** coordinates
|
||||||
|
*/
|
||||||
|
virtual void prepare_for_render (Rect const & area) const { }
|
||||||
|
|
||||||
/** Adds one or more items to the vector @param items based on their
|
/** Adds one or more items to the vector @param items based on their
|
||||||
* covering @param point which is in **window** coordinates
|
* covering @param point which is in **window** coordinates
|
||||||
*
|
*
|
||||||
@ -309,6 +316,7 @@ protected:
|
|||||||
|
|
||||||
void add_child_bounding_boxes (bool include_hidden = false) const;
|
void add_child_bounding_boxes (bool include_hidden = false) const;
|
||||||
void render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
|
void render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
|
||||||
|
void prepare_for_render_children (Rect const & area) const;
|
||||||
|
|
||||||
Duple scroll_offset() const;
|
Duple scroll_offset() const;
|
||||||
Duple position_offset() const;
|
Duple position_offset() const;
|
||||||
|
@ -37,6 +37,12 @@ Container::Container (Item* parent, Duple const & p)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Container::prepare_for_render (Rect const & area) const
|
||||||
|
{
|
||||||
|
Item::prepare_for_render_children (area);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Container::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
Container::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||||
{
|
{
|
||||||
|
@ -830,6 +830,43 @@ Item::render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context)
|
|||||||
--render_depth;
|
--render_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Item::prepare_for_render_children (Rect const & area) const
|
||||||
|
{
|
||||||
|
if (_items.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_lut ();
|
||||||
|
std::vector<Item*> items = _lut->get (area);
|
||||||
|
|
||||||
|
for (std::vector<Item*>::const_iterator i = items.begin(); i != items.end(); ++i) {
|
||||||
|
|
||||||
|
if (!(*i)->visible ()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect item_bbox = (*i)->bounding_box ();
|
||||||
|
|
||||||
|
if (!item_bbox) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect item = (*i)->item_to_window (item_bbox, false);
|
||||||
|
Rect d = item.intersection (area);
|
||||||
|
|
||||||
|
if (d) {
|
||||||
|
Rect draw = d;
|
||||||
|
if (draw.width() && draw.height()) {
|
||||||
|
(*i)->prepare_for_render (area);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Item does not intersect with visible canvas area
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Item::add_child_bounding_boxes (bool include_hidden) const
|
Item::add_child_bounding_boxes (bool include_hidden) const
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user