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 » Problem adapting child Ctrl to scroller example code
Problem adapting child Ctrl to scroller example code [message #51500] Fri, 05 April 2019 09:35 Go to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
I end up with some strange pileup of Ctrls at either end of the document if I scroll quickly. What am I doing wrong?

#include <CtrlLib/CtrlLib.h>

using namespace Upp;
int count = 0;

struct ChildTest : Ctrl {
	int num=0;

	ChildTest() {
		SetFrame(BlackFrame());
		num = count;
		count++;
		SetRect(0, 0, 200, 50);
	}
	
	void Paint(Draw& w) override {
		LogPos lpos = GetPos();
		int y = lpos.y.GetA();
		auto sz = GetSize();
			
		w.DrawRect(sz, Color{ 255, 0, 0 } );
		
		String pos;
		pos << "item: " << num << " x: " << lpos.x.GetA() << " y: " << lpos.y.GetA();
		w.DrawText(10, 10, pos, Arial(14).Bold(), Color(0,0,0));
	}
};

struct App : TopWindow {
	ScrollBar          sb;
	int                count;
	Vector<ChildTest*> items;
	
	int GetLineHeight() {
		return 50;
	}

	virtual void Paint(Draw& w)
	{
		Size sz = GetSize();
		w.DrawRect(sz, SWhite);
		int fcy = GetLineHeight();
		int i = sb / fcy;
		int y = i * fcy - sb;
		
		String sbPos;
		sbPos << i;
		
		while(i < count && y < sz.cy) {
			auto item = items[i++];
			item->SetRect(0, y, 200, 45);
			y += fcy;
		}
		
		w.DrawText(200, 10, sbPos, Arial(14).Bold(), Color(0,0,0));
	}

	virtual void Layout()
	{
		sb.SetPage(GetSize().cy);
	}

	virtual void MouseWheel(Point, int zdelta, dword)
	{
		sb.Wheel(zdelta);
	}

	bool Key(dword key, int)
	{
		return sb.VertKey(key);
	}

	void SetCount(int n)
	{
		count = n;
		sb.SetTotal(n * GetLineHeight());
	}

	~App() {
		for(auto item : items) {
			delete item;
		}
	}

	App() {
		Sizeable().Zoomable().BackPaint();
		AddFrame(sb);
		sb.WhenScroll = [=] { Refresh(); };
		sb.SetLine(GetLineHeight());
		
		for(int i = 0; i < 100; i++) {
			ChildTest* ctrl = new ChildTest();
			ctrl->SetRect(0, i * 50, 200, 45);
			items.Add(ctrl);
			AddChild(ctrl);
		}
	}
};

GUI_APP_MAIN
{
	App app;
	app.SetRect(0, 0, 250, 500);
	app.SetCount(100);
	app.Run();
}


Re: Problem adapting child Ctrl to scroller example code [message #51501 is a reply to message #51500] Fri, 05 April 2019 10:23 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Well, the reason is pretty obvious here - you are only setting new positions to a subset of widgets, so the rest of them stays where they are.

I have fixed it for you, being there I could not resist to "beautify" and "make more U++" it... Smile

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

struct ChildTest : Ctrl {
	int num=0;
	
	ChildTest(int num) : num(num) {
		SetFrame(BlackFrame());
		SetRect(0, 0, 200, 50);
	}
	
	void Paint(Draw& w) override {
		LogPos lpos = GetPos();
		int y = lpos.y.GetA();
		Size sz = GetSize();
			
		w.DrawRect(sz, AdjustIfDark(Color{ 255, 0, 0 }) );
		
		String pos;
		pos << "item: " << num << " x: " << lpos.x.GetA() << " y: " << lpos.y.GetA();
		w.DrawText(Zx(10), Zy(10), pos, Arial(14).Bold());
	}
};

struct App : TopWindow {
	ScrollBar          sb;
	Array<ChildTest>   items;
	
	int GetLineHeight() {
		return Zy(50);
	}

	void Sync() {
		for(int i = 0; i < items.GetCount(); i++)
			items[i].SetRect(0, i * GetLineHeight() - sb, Zx(200), Zy(45));
	}

	void Paint(Draw& w) override
	{
		Size sz = GetSize();
		w.DrawRect(sz, SWhite());
	}

	void Layout() override
	{
		sb.SetPage(GetSize().cy);
	}

	void MouseWheel(Point, int zdelta, dword) override
	{
		sb.Wheel(zdelta);
	}

	bool Key(dword key, int) override
	{
		return sb.VertKey(key);
	}

	App() {
		Sizeable().Zoomable(); // Backpaint is now default
		
		for(int i = 0; i < 100; i++)
			Add(items.Create<ChildTest>(i));
		
		AddFrame(sb);
		sb.WhenScroll = [=] { Sync(); };
		sb.SetLine(GetLineHeight());
		sb.SetTotal(items.GetCount() * GetLineHeight());

		Sync();
	}
};

GUI_APP_MAIN
{
	App app;
	app.SetRect(0, 0, Zx(250), Zy(500));
	app.Run();
}


Most important changes: Doing that in Paint is ugly, using 'new' is shunned upon. And you better make your app ready for UHD...
Re: Problem adapting child Ctrl to scroller example code [message #51505 is a reply to message #51501] Fri, 05 April 2019 19:10 Go to previous message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
Hey, that does look a lot nicer and this also helps me get rid of new in some other places I was using it. I wanted to avoid using new too but I was unaware of Create. It's funny, I only asked to solve one problem and you ended up solving several for me that I hadn't yet gotten around to asking about. You have absolved me of my future crimes Surprised

Thank you again for being so helpful.
Previous Topic: override TrayIcon::WindowProc
Next Topic: capture mouse and limit all events to window
Goto Forum:
  


Current Time: Fri Mar 29 08:30:24 CET 2024

Total time taken to generate the page: 0.01569 seconds