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 » TreeCtrl » TreeCtrl Scroll triggers Parent Refresh
TreeCtrl Scroll triggers Parent Refresh [message #11311] Mon, 03 September 2007 15:50 Go to next message
nixnixnix is currently offline  nixnixnix
Messages: 415
Registered: February 2007
Location: Kelowna, British Columbia
Senior Member
I use a SplitterFrame to split my window into a tree view and a map view (GIS-style app). My map view can take a while to draw sometimes. I have noticed that dragging the scroll bar in the tree view gets slower as my map view takes longer to draw and so it seems that the tree view is triggering a Refresh in the SplitterFrame. Is there any way to disable this please? I've searched through TreeCtrl.cpp and can't find any obvious call to parent to refresh.

Nick
Re: TreeCtrl Scroll triggers Parent Refresh [message #11312 is a reply to message #11311] Mon, 03 September 2007 18:23 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Can be a bug.

BTW, there is nice way how to examine these issues. Put into your MAIN:

Ctrl::ShowRepaint(50);

(the number is in milliseconds).

If your hypothesis is proved true, do you think you could gather a simple testcase?

Mirek
Re: TreeCtrl Scroll triggers Parent Refresh [message #11313 is a reply to message #11312] Mon, 03 September 2007 18:34 Go to previous messageGo to next message
nixnixnix is currently offline  nixnixnix
Messages: 415
Registered: February 2007
Location: Kelowna, British Columbia
Senior Member
Hi Mirek,

I didn't put a test case together yet as my hypothesis was false.

What is actually happening is my nodes are set at width 300 and the initial width of my TreeCtrl is 250 so the nodes are overlapping onto the other window and invalidating that window triggering a repaint. (they are also invalidating the toolbar and menu bar above the TreeCtrl and the status bar below it)

IMO anything in the TreeCtrl should be clipped to the TreeCtrl. What do you think? Is there a command to do this or is this a bug?

Want a test case?

Nick

p.s. nice trick with the bright red invalidation Smile

[Updated on: Mon, 03 September 2007 18:35]

Report message to a moderator

Re: TreeCtrl Scroll triggers Parent Refresh [message #11314 is a reply to message #11313] Mon, 03 September 2007 20:38 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Ooops, a bug. U++ default behaviour for Display is to Clip.

Quick fix:

void TreeCtrl::Paint(Draw& w)
{
	SyncTree();
	Size sz = GetSize();
	Point org = sb;
	scroller.Set(org);
	if(!nobg)
		w.DrawRect(sz, SColorPaper);
	int levelcx2 = levelcx >> 1;
	for(int i = 0; i < line.GetCount(); i++) {
		Line& l = line[i];
		if(l.ll >= 0) {
			int yl = line[i].y + item[l.itemi].GetSize().cy - org.y;
			int yh = line[l.ll].y + item[line[l.ll].itemi].GetSize().cy / 2 - org.y;
			if(yh >= 0 && yl < sz.cy) {
				int x = levelcx + levelcx * l.level + levelcx2 - org.x;
				w.DrawRect(x, yl, 1, yh - yl, SColorShadow);
			}
		}
	}
	Rect dri;
	for(int i = FindLine(org.y); i < line.GetCount(); i++) {
		Line& l = line[i];
		const Item& m = item[l.itemi];
		Size msz = m.GetSize();
		Size isz = m.image.GetSize();
		Size vsz = m.GetValueSize();
		int y = l.y - org.y;
		if(y > sz.cy)
			break;
		int x = 0;
		x = levelcx + l.level * levelcx - org.x;
		Point op = Point(x - levelcx2, y + msz.cy / 2);
		Rect r = RectC(x, y, vsz.cx + 2 * m.margin, msz.cy);
		if(l.itemi == dropitem) {
			dri = r;
			if(i == 0)
				dri.top++;
		}
		if(w.IsPainting(0, y, sz.cx, msz.cy)) {
			w.DrawRect(op.x, op.y, levelcx2, 1, SColorShadow);
			if(m.canopen || m.child.GetCount()) {
				Image im = m.isopen ? CtrlImg::treeminus() : CtrlImg::treeplus();
				op -= im.GetSize() / 2;
				w.DrawImage(op.x, op.y, im);
			}
			w.DrawImage(x, y + (msz.cy - isz.cy) / 2, m.image);
			x += isz.cx;
			Color fg, bg;
			dword st;
			const Display *d = GetStyle(i, fg, bg, st);
			if(!(m.ctrl && m.ctrl->IsWantFocus())) {
				w.DrawRect(x, y, vsz.cx + 2 * m.margin, msz.cy, bg);
				Rect r = RectC(x + m.margin, y + (msz.cy - vsz.cy) / 2, vsz.cx, vsz.cy);
				w.Clip(r);
				d->Paint(w, r, m.value, fg, bg, st);
				w.End();
				if(i == cursor && !nocursor && multiselect && GetSelectCount() != 1 && HasFocus()
				   && !IsDragAndDropTarget())
					DrawFocus(w, r, st & Display::SELECT ? SColorPaper() : SColorText());
			}
		}
	}
	if(dropitem >= 0 && dropinsert)
		DrawHorzDrop(w, dri.left - 2, dropinsert < 0 ? dri.top : dri.bottom - 1,
		             sz.cx - dri.left + 2);
}


Mirek
Re: TreeCtrl Scroll triggers Parent Refresh [message #11321 is a reply to message #11314] Tue, 04 September 2007 18:06 Go to previous messageGo to next message
nixnixnix is currently offline  nixnixnix
Messages: 415
Registered: February 2007
Location: Kelowna, British Columbia
Senior Member
Hi Mirek,

I copied and pasted your code into my TreeCtrl.cpp (did a bomb) and it still overpaints. Did you try it with Option Ctrls?

Nick
Re: TreeCtrl Scroll triggers Parent Refresh [message #11331 is a reply to message #11321] Wed, 05 September 2007 21:45 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Do you think you can provide a testcase?

Mirek
Re: TreeCtrl Scroll triggers Parent Refresh [message #11336 is a reply to message #11331] Thu, 06 September 2007 00:36 Go to previous messageGo to next message
nixnixnix is currently offline  nixnixnix
Messages: 415
Registered: February 2007
Location: Kelowna, British Columbia
Senior Member
Absolutely, here is the simplest I can find (I added the frames to show it overpainting - they are not necessary).


#include "CtrlLib/CtrlLib.h"

using namespace Upp;


struct App : TopWindow {
	TreeCtrl   tree;
	SplitterFrame m_sf;
	ToolBar tools;
	StatusBar status;
	MenuBar menu;

	typedef App CLASSNAME;

	void DropInsert(int parent, int ii, PasteClip& d)
	{
		tree.AdjustAction(parent, d);
		if(AcceptInternal<TreeCtrl>(d, "mytreedrag")) {
			tree.InsertDrop(parent, ii, d);
			tree.SetFocus();
			return;
		}
		if(AcceptText(d)) {
			tree.SetCursor(tree.Insert(parent, ii, Image(), GetString(d)));
			tree.SetFocus();
			return;
		}
	}

	void Drag()
	{
		if(tree.DoDragAndDrop(InternalClip(tree, "mytreedrag"),
		                       tree.GetDragSample()) == DND_MOVE)
			tree.RemoveSelection();
	}

	App() {
		Ctrl::ShowRepaint(50);

		AddFrame(TopSeparatorFrame());
		AddFrame(menu);
		AddFrame(TopSeparatorFrame());
		AddFrame(tools);
		AddFrame(TopSeparatorFrame());
		AddFrame(status);
		
		
		AddFrame(m_sf.Left(tree.SizePos(),250));
		AddFrame(InsetFrame());
		
//		Add(tree.SizePos());

		Vector<int> parent, parent2;
		Option* option = new Option[10000]; // mine
		parent.Add(0);
		tree.SetRoot(Image(), "The Tree");
		for(int i = 1; i < 10000; i++) 
		{
			option[i].SetLabel(FormatIntRoman(i, true)); // mine
	
			TreeCtrl::Node node(CtrlImg::File(),option[i],300);	

			parent.Add(tree.Add(parent[rand() % parent.GetCount()], node)); // mine

//			parent.Add(tree.Add(parent[rand() % parent.GetCount()], CtrlImg::File(),
//					            FormatIntRoman(i, true)));
			if((rand() & 3) == 0)
				tree.Open(parent.Top());
		}
		tree.Open(0);
		tree.WhenDropInsert = THISBACK(DropInsert);
		tree.WhenDrag = THISBACK(Drag);
		tree.MultiSelect();
		Sizeable();
		
	}
};



GUI_APP_MAIN
{
	App().Run();
}


Please let me know if you need more info.

Nick
Re: TreeCtrl Scroll triggers Parent Refresh [message #11422 is a reply to message #11336] Wed, 12 September 2007 12:08 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Should be fixed, sorry for delay, took quite a lot of time to find it....

Quick fix:

Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe)
{
	if(!inframe) {
		r &= Rect(GetSize());
		r.Offset(GetView().TopLeft());
	}
	if(parent) {
		r.Offset(GetRect().TopLeft());
		return parent->GetTopRect(r, InFrame());
	}
	return this;
}

Re: TreeCtrl Scroll triggers Parent Refresh [message #11430 is a reply to message #11422] Wed, 12 September 2007 14:54 Go to previous message
nixnixnix is currently offline  nixnixnix
Messages: 415
Registered: February 2007
Location: Kelowna, British Columbia
Senior Member
No worries. Yup that does the trick.

Thanks,

Nick
Previous Topic: Right Clicking Tree Nodes?
Next Topic: Like the new Drag and Drop TreeCtrl but...
Goto Forum:
  


Current Time: Fri Mar 29 08:46:25 CET 2024

Total time taken to generate the page: 0.01672 seconds