Home » U++ Library support » TreeCtrl » TreeCtrl Scroll triggers Parent Refresh
TreeCtrl Scroll triggers Parent Refresh [message #11311] |
Mon, 03 September 2007 15:50 |
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 #11313 is a reply to message #11312] |
Mon, 03 September 2007 18:34 |
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
[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 |
|
mirek
Messages: 13984 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 #11336 is a reply to message #11331] |
Thu, 06 September 2007 00:36 |
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
|
|
|
|
|
Goto Forum:
Current Time: Mon Jun 10 12:45:24 CEST 2024
Total time taken to generate the page: 0.01363 seconds
|