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 would I virtualize a scrollable view to dynamically load Ctrls?
How would I virtualize a scrollable view to dynamically load Ctrls? [message #58431] Thu, 19 May 2022 19:07 Go to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 150
Registered: June 2011
Experienced Member
Quick example:

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

struct App : TopWindow {
    ScrollBar   sb;
    Array<RichTextCtrl> items;
    
    int GetLineHeight() {
        return 25;
    }

    void Sync() {
        int startY = 10;
        Rect pr = GetRect();
        auto sz = GetSize();
        
        for(RichTextCtrl& item : items) {
            Rect r = item.GetRect();

            item.SetRect(r.left, startY - sb, pr.GetWidth(), item.GetHeight(sz.cx));
            startY += r.GetHeight() + 5;
        }
        
        sb.SetTotal(startY);
    }

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

    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();
        
        for(int i = 0; i < 1000; i++) {
            RichTextCtrl& item = items.Create<RichTextCtrl>();
            
            item.SetData(
                Format(
                "[@(%d.%d.%d) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et "
                "dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip "
                "ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu "
                "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
                "mollit anim id est laborum.]",
                (int)Random(255), (int)Random(255), (int)Random(255))
                );
            
            item.SetZoom(Zoom(1, 1));
            item.HSizePos(0, 0).VSizePos(0, 0);
            item.SetRect(0, 0, 0, item.GetHeight(250));
            item.IgnoreMouse();
            
            Add(item);
        }
        
        Sync();
        
        sb.Enable();
        sb.WhenScroll = [this] { Sync(); };
        sb.SetLine(GetLineHeight());
        AddFrame(sb);
    }
};

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


I don't know if there is any facility built into U++ for this already but I'd like to dynamically load and unload a bunch of Ctrls as I scroll (web equivalent a virtual scroller) so that I don't have a bunch of redraws of Ctrls that aren't visible in the view. As you can see from the example it can get quite expensive to resize the window if it has thousands of controls.

How would I accomplish this?
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58479 is a reply to message #58431] Tue, 31 May 2022 11:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13663
Registered: November 2005
Ultimate Member
Placing those text in Paint is not a good idea. The time is spent in RichTextCtrl::GetHeight, which is slow. I have tried to optimise

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

struct App : TopWindow {
	ScrollBar   sb;
	Array<RichTextCtrl> items;
	
	int GetLineHeight() {
		return 25;
	}

	void Scroll() {
		Size sz = GetSize();
		int sy = sb;
		int y = 0;
		for(RichTextCtrl& item : items) {
			int h = item.GetRect().GetHeight();
			if(sz.cx && y + h > sy && y < sy + sz.cy) {
				item.Show();
				item.SetRect(0, y - sy, sz.cx, h);
			}
			else
				item.Hide();
			y += h + 5;
		}
	}

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

	void Layout() override {
		Size sz = GetSize();
		sb.SetPage(sz.cy);

		if(sz.cx) {
			int y = 0;
			for(RichTextCtrl& item : items) { // compute the height - that can be slow
				Rect r = item.GetRect();
				if(r.GetWidth() != sz.cx) {
					int h = item.GetHeight(sz.cx);
					item.SetRect(0, 0, sz.cx, h);
					item.Hide();
					y += h + 5;
				}
			}
			sb.SetTotal(y);
		}
		
		Scroll();
	}

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

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

	App() {
		Sizeable().Zoomable();
		
		for(int i = 0; i < 10000; i++) {
			RichTextCtrl& item = items.Create<RichTextCtrl>();
			
			item.SetData(
				Format(
				"[@(%d.%d.%d) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et "
				"dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip "
				"ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu "
				"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
				"mollit anim id est laborum.]",
				(int)Random(255), (int)Random(255), (int)Random(255))
				);
			
			item.SetZoom(Zoom(1, 1));
			item.SetRect(0, 0, 0, 0);
			item.IgnoreMouse();
			
			Add(item);
		}
		
		sb.Enable();
		sb.WhenScroll = [this] { Scroll(); };
		sb.SetLine(GetLineHeight());
		AddFrame(sb);
	}
};

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


Which works fine for 10000 texts; with 100000 texts it is slow again, but the time once again is lost in GetHeight - that one basically needs to typeset that paragraph with all typographic rules. I can try to look into it, OTOH as we will need to support advanced composition in future, chances are it will only get slower then.

Mirek
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58482 is a reply to message #58479] Tue, 31 May 2022 12:41 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 150
Registered: June 2011
Experienced Member
mirek wrote on Tue, 31 May 2022 11:13
Placing those text in Paint is not a good idea. The time is spent in RichTextCtrl::GetHeight, which is slow. I have tried to optimise

----------------8<-------------------

Which works fine for 10000 texts; with 100000 texts it is slow again, but the time once again is lost in GetHeight - that one basically needs to typeset that paragraph with all typographic rules. I can try to look into it, OTOH as we will need to support advanced composition in future, chances are it will only get slower then.

Mirek


Thanks for giving it a shot, Mirek. Unfortunately with even 10,000 ctrls on my older machine either application is so slow during a window resize that I can't even tell which one is faster by looking at it. I'll have to see if it's a problem with my compositor.

If the rich ctrl will allow me to do more in the future that sounds like a good thing. Maybe it means I could stop using thousands of them and instead just use one. Until then it looks like I'll have to come up with some form of dynamic loading.
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58483 is a reply to message #58482] Tue, 31 May 2022 14:39 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13663
Registered: November 2005
Ultimate Member
I am afraid that with thousands of paragraphs, it will still be slow determining the height for given with (e.g. RichTextCtrl needs to do that in Layout anyway). Note that if you load some really big text in MS Word or OpenOffice writer, it can be slow as well before he reformats everything. In you current example, you need to typeset about 4 millions glyphs... Smile

It is strange it is slow on your machine though. What exactly is slow, scrolling?

Mirek
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58487 is a reply to message #58483] Tue, 31 May 2022 21:27 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 150
Registered: June 2011
Experienced Member
mirek wrote on Tue, 31 May 2022 14:39
I am afraid that with thousands of paragraphs, it will still be slow determining the height for given with (e.g. RichTextCtrl needs to do that in Layout anyway). Note that if you load some really big text in MS Word or OpenOffice writer, it can be slow as well before he reformats everything. In you current example, you need to typeset about 4 millions glyphs... Smile

It is strange it is slow on your machine though. What exactly is slow, scrolling?

Mirek


Scrolling is fine. Resizing just kills it. This is on linux though, I don't know if you were running it on Windows. KDE, cinnamon, lxde - doesn't matter on any DE I've tested even with compositing turned off.

But yeah, given the amount it has to do to the text I'm not surprised it bogs down. That's a lot of work to do just for a transitional effect. I thought the problem, other than the sheer number of items was in GetHeight too, promise to use the profiler code in the future to know for sure. One thing I was really impressed with was how little memory it used.
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58489 is a reply to message #58487] Wed, 01 June 2022 15:34 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13663
Registered: November 2005
Ultimate Member
jjacksonRIAB wrote on Tue, 31 May 2022 21:27
mirek wrote on Tue, 31 May 2022 14:39
I am afraid that with thousands of paragraphs, it will still be slow determining the height for given with (e.g. RichTextCtrl needs to do that in Layout anyway). Note that if you load some really big text in MS Word or OpenOffice writer, it can be slow as well before he reformats everything. In you current example, you need to typeset about 4 millions glyphs... Smile

It is strange it is slow on your machine though. What exactly is slow, scrolling?

Mirek


Scrolling is fine. Resizing just kills it. This is on linux though, I don't know if you were running it on Windows. KDE, cinnamon, lxde - doesn't matter on any DE I've tested even with compositing turned off.


That part is actually not influenced by DE nor system in any way... I believe 99% of time is spent in

RichPara::Lines RichPara::FormatLines(int acx) const

RichText/ParaType.cpp:237

Mirek
Re: How would I virtualize a scrollable view to dynamically load Ctrls? [message #58490 is a reply to message #58489] Wed, 01 June 2022 15:57 Go to previous message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 150
Registered: June 2011
Experienced Member
mirek wrote on Wed, 01 June 2022 15:34
jjacksonRIAB wrote on Tue, 31 May 2022 21:27
mirek wrote on Tue, 31 May 2022 14:39
I am afraid that with thousands of paragraphs, it will still be slow determining the height for given with (e.g. RichTextCtrl needs to do that in Layout anyway). Note that if you load some really big text in MS Word or OpenOffice writer, it can be slow as well before he reformats everything. In you current example, you need to typeset about 4 millions glyphs... Smile

It is strange it is slow on your machine though. What exactly is slow, scrolling?

Mirek


Scrolling is fine. Resizing just kills it. This is on linux though, I don't know if you were running it on Windows. KDE, cinnamon, lxde - doesn't matter on any DE I've tested even with compositing turned off.


That part is actually not influenced by DE nor system in any way... I believe 99% of time is spent in

RichPara::Lines RichPara::FormatLines(int acx) const

RichText/ParaType.cpp:237

Mirek


Having not tested it myself I'll defer to your experience but my rationale for how it could happen is that perhaps one DE/WM may fire resize events more frequently than another but it was just a guess. More likely your machine is just significantly faster than mine. Very Happy
Previous Topic: Proper SplitterFrame removal++
Next Topic: What happened to the caret methods?
Goto Forum:
  


Current Time: Tue Aug 09 15:48:11 CEST 2022

Total time taken to generate the page: 0.01215 seconds