On Monday 15 July 2002 10:39 am, Juergen Vigna wrote:
> Angus Leeming wrote:
> > Is there a function
> >     bool insetContainsInset(Inset const & container, Inset const &
> > containee);
> >
> > If so, what's it called !
>
> No there is no such function the one existant is:
>      bool isInsetInInset(Inset *)
> but you could just change the parameters to your needs or add it if you
> really need it. But could you please explain me in short for what you
> need this?

Sure. Attached are GraphicsSupport.[Ch] so you can see the function 
isInsetVisible. You can see also that I need to fill in insetContainsInset. 
I'm sure that I'll be able to use isInsetInInset. For that info: thank you.

I use this isInsetVisible function to check whether I really should start 
loading a graphic in 
        GraphicLoader::startLoading(Inset const & inset, BufferView const & bv),
which is called from the Inset::draw method of either an InsetGraphics or an 
inset with a Preview.

Here's the relevant GraphicLoader code. It works like a charm.

Angus

Loader::Impl::Impl(Loader & parent, Params const & params)
        : status_(WaitingToLoad), params_(params), parent_(parent),
          timer(2000, Timeout::ONETIME), view(0)
{
        timer.timeout.connect(boost::bind(&Impl::checkedLoading, this));
}


void Loader::Impl::startLoading(Inset const & inset, BufferView const & bv)
{
        if (status_ != WaitingToLoad || timer.running())
                return;

        InsetList::const_iterator it  = insets.begin();
        InsetList::const_iterator end = insets.end();
        it = std::find(it, end, &inset);
        if (it == end)
                insets.push_back(&inset);
        view = &bv;

        timer.start();
}


namespace {

struct FindVisibleInset {

        FindVisibleInset(std::list<VisibleParagraph> const & vps) : vps_(vps) {}

        bool operator()(Inset const * inset_ptr)
        {
                if (!inset_ptr)
                        return false;
                return isInsetVisible(*inset_ptr, vps_);
        }
        
private:
        std::list<VisibleParagraph> const & vps_;
};

} // namespace anon


void Loader::Impl::checkedLoading()
{
        if (insets.empty() || !view)
                return;

        std::list<VisibleParagraph> const vps = getVisibleParagraphs(*view);

        InsetList::const_iterator it  = insets.begin();
        InsetList::const_iterator end = insets.end();

        it = std::find_if(it, end, FindVisibleInset(vps));

        // One of the insets is visible, so start loading the image.
        if (it != end)
                cached_item_->startLoading();
}
// -*- C++ -*-
/**
 *  \file GraphicsSupport.h
 *  Copyright 2002 the LyX Team
 *  Read the file COPYING
 *
 * \author Angus Leeming <[EMAIL PROTECTED]>
 */

#ifndef GRAPHICSSUPPORT_H
#define GRAPHICSSUPPORT_H

#ifdef __GNUG__
#pragma interface
#endif

#include "support/types.h"
#include <list>

class BufferView;
class Inset;
class Paragraph;

/** A Paragraph * together with delimiters for the start and end positions
    of visibility.
 */
struct VisibleParagraph {
	///
	VisibleParagraph() : par(0), start(0), end(0) {}
	///
	VisibleParagraph(Paragraph * p, lyx::pos_type s, lyx::pos_type e)
		: par(p), start(s), end(e) {}
	///
	Paragraph * par;
	///
	lyx::pos_type start;
	///
	lyx::pos_type end;
};


/// Returns a list of all Paragraphs currently visible in bv.
std::list<VisibleParagraph> const getVisibleParagraphs(BufferView const & bv);

/** Given this data, check whether inset lies within it and is, therefore,
 *  visible.
 */
bool isInsetVisible(Inset const & inset, std::list<VisibleParagraph> const &);

#endif // GRAPHICSSUPPORT_H
/**
 *  \file GraphicsSupport.C
 *  Copyright 2002 the LyX Team
 *  Read the file COPYING
 *
 * \author Angus Leeming <[EMAIL PROTECTED]>
 */

#include <config.h>

#ifdef __GNUG__
#pragma implementation
#endif

#include "GraphicsSupport.h"

#include "BufferView.h"
#include "lyxtext.h"
#include "lyxrow.h"
#include "paragraph.h"
#include "frontends/Painter.h"


typedef std::list<VisibleParagraph> VPList;


VPList const getVisibleParagraphs(BufferView const & bv)
{
	// top_y is not const because it's reset by getRowNearY.
	int top_y = bv.text->first_y;
	Row const * row = bv.text->getRowNearY(top_y);

	int const bv_height = bv.painter().paperHeight();

	VPList vps;
	Row const * last_row = 0;

	for (int height = 0; row && height < bv_height; row = row->next()) {
		height += row->height();

		if (vps.empty() || vps.back().par != row->par()) {
			vps.push_back(VisibleParagraph(row->par(),
						       row->pos(),
						       row->par()->size()));
		}

		last_row = row;
	}

	// If the end of the final paragraph is not visble,
	// update vps.back().end
	if (last_row && last_row->next() &&
	    last_row->par() == last_row->next()->par()) {
		vps.back().end = last_row->next()->pos();
	}

	return vps;
}


namespace {

bool insetContainsInset(Inset const & container, Inset const & containee)
{
	return false;
}

} // namespace anon


bool isInsetVisible(Inset const & inset, VPList const & vps)
{
	if (vps.empty())
		return false;

	VPList::const_iterator vpit  = vps.begin();
	VPList::const_iterator vpend = vps.end();

	for (; vpit != vpend; ++vpit) {
		Paragraph * par = vpit->par;
		Paragraph::inset_iterator iit  = par->inset_iterator_begin();
		Paragraph::inset_iterator iend = par->inset_iterator_end();

		for (; iit != iend; ++iit) {
			lyx::pos_type const pos = iit.getPos();
			if (pos >= vpit->start && pos <= vpit->end) {
				if (*iit == &inset)
					return true;
				if (insetContainsInset(**iit, inset))
					return true;
			}
		}
	}

	return false;
}

Reply via email to