Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » How to implent a rubber band Class in u++
Re: How to implent a rubber band Class in u++ [message #17298 is a reply to message #17297] Wed, 06 August 2008 11:04 Go to previous messageGo to previous message
mrjt is currently offline  mrjt
Messages: 705
Registered: March 2007
Location: London
Contributor
I can think of two possible optimisations (besides PolyLine, which is definitely the first one to use)

1- Avoid adding adjacent collinear points. In practice this is a very minor optimisation except for special cases, but it appeals to my sense of correctness.
class RubberBand : public LocalLoop
{
public:
	virtual void MouseMove(Point p, dword keyflags) 	{ AddPoint(p); GetMaster().Refresh(); }
	virtual void LeftUp(Point p, dword keyflags)    	{ EndLoop(); }
	virtual void RightUp(Point p, dword keyflags)   	{ EndLoop(); }

	const Vector<Point> &	GetPoints()					{ return points; }
	void 					Clear()						{ points.Clear(); }
private:
	Vector<Point> points;
	
	void AddPoint(const Point &newp);
};

void RubberBand::AddPoint(const Point &newp)
{
	if (points.GetCount() < 2)
		return points.Add(newp);
	// Get line vectors
	const Point &p = points[points.GetCount()-2];
	Point p1 = points.Top() - p;
	Point p2 = newp - p;
	// If gradient is different, add the new point
	if (p1.x*p2.y - p2.x*p1.y)
		points.Add(newp);
	// Otherwise update last points
	else
		points.Top() = newp;
}


2- Use a back buffer. Providing you have a static background (one that will not change while the rubber band is being drawn), you can use a back buffer to cache the background + the current rubber band and only draw the last line.

This was a major improvement for me, eliminating flickering entirely.
	RubberBand 	band;
	BackDraw 	back;
	Size	 	backsz;
	
	void LeftDown(Point p, dword keyflags)
	{
		band.Clear();
		band.SetMaster(*this);
		Size sz = GetSize();
		if (sz != backsz) {
		    back.Create(sz);
		 	backsz = sz;   
		}
		Paint(back);
		band.Run();
		Refresh();
	}
	
	void Paint(Draw& w)
	{
		const Vector<Point> &p = band.GetPoints();
		if (!band.InLoop()) {
			// Normal painting
			w.DrawRect(GetSize(), White);	
			if (p.GetCount() >= 2) {
				w.DrawPolyline(p);	
				w.DrawLine(p[p.GetCount()-1], p[0]);
			}
						
		}
		else {
                        // RubberBand painting
			if (p.GetCount() >= 2)
				back.DrawLine(p[p.GetCount()-2], p.Top());
			back.Put(w, 0, 0);
			w.DrawText(4, 4, AsString(p.GetCount()));
		}
	}
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: FileList problems with extensions and pop-ups
Next Topic: How to turn off special chars in RichEdit?
Goto Forum:
  


Current Time: Mon Jun 17 06:44:04 CEST 2024

Total time taken to generate the page: 0.02581 seconds