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  |
jjacksonRIAB
Messages: 227 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   |
 |
mirek
Messages: 14255 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... 
#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...
|
|
|
|
Goto Forum:
Current Time: Sat Apr 26 14:48:27 CEST 2025
Total time taken to generate the page: 0.00717 seconds
|