|
|
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » Drop list is not shown
|
|
|
|
|
|
Re: Drop list is not shown [message #43888 is a reply to message #43884] |
Fri, 14 November 2014 16:10 |
|
mirek
Messages: 14105 Registered: November 2005
|
Ultimate Member |
|
|
OK, that narrows it down. As I am still clueless what might be wrong, might I ask for some logging?
void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
if(inpopup)
return;
inpopup++;
DoClose();
int h = AddFrameSize(width, min(droplines * GetLineCy(), GetTotalCy())).cy;
Rect rt = RectC(x, bottom, width, h);
Rect area = Ctrl::GetWorkArea(Point(x, top));
bool up = false;
if(rt.bottom > area.bottom) {
up = true;
rt.top = top - h;
rt.bottom = rt.top + h;
}
open = false;
popup.Create();
popup->table = this;
if(up) {
popup->SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom));
popup->Add(TopPos(0, rt.Height()).LeftPos(0, rt.Width()));
}
else {
popup->SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1));
popup->Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));
}
DLOG("---------------------------");
DDUMP(popup->GetRect());
DDUMP(rt);
if(GUI_PopUpEffect()) {
CenterCursor();
popup->PopUp(owner, true, true, GUI_DropShadows());
SetFocus();
Ctrl::ProcessEvents();
Animate(*popup, rt, GUIEFFECT_SLIDE);
// Ctrl::Remove();
}
if(!open) {
popup->SetRect(rt);
if(!popup->IsOpen())
popup->PopUp(owner, true, true, GUI_DropShadows());
CenterCursor();
SetFocus();
open = true;
}
inpopup--;
}
void Animate(Ctrl& c, const Rect& target, int type)
{
if(type < 0)
type = GUI_PopUpEffect();
Rect r0 = c.GetRect();
DDUMP(r0);
dword time0 = GetTickCount();
int anitime = 150;
#ifdef SLOWANIMATION
anitime = 1500;
#endif
if(type)
for(;;) {
int t = int(GetTickCount() - time0);
if(t > anitime)
break;
if(type == GUIEFFECT_SLIDE) {
Rect r = r0;
if(r.left > target.left)
r.left -= ((r.left - target.left)* t) / anitime;
if(r.top > target.top)
r.top -= ((r.top - target.top) * t) / anitime;
if(r.right < target.right)
r.right += ((target.right - r.right) * t) / anitime;
if(r.bottom < target.bottom)
r.bottom += ((target.bottom - r.bottom) * t) / anitime;
if(r.GetWidth() > target.GetWidth())
r.right = r.left + target.GetWidth();
if(r.GetHeight() > target.GetHeight())
r.bottom = r.top + target.GetHeight();
DDUMP(r);
c.SetRect(r);
if(r == target)
break;
}
else
if(type == GUIEFFECT_FADE)
c.SetAlpha((byte)(255 * t / anitime));
else
break;
c.Sync();
Sleep(0);
#ifdef SLOWANIMATION
Sleep(100);
#endif
}
DDUMP(target);
c.SetRect(target);
c.SetAlpha(255);
}
[
|
|
|
|
Re: Drop list is not shown [message #43903 is a reply to message #43888] |
Sun, 16 November 2014 15:51 |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |
|
|
after I clicked drop list (and only horizontal black line is drawn) :
popup->GetRect() = [1130, 343] - [1347, 344] : (217, 1)
rt = [1130, 343] - [1347, 615] : (217, 272)
after I closed the settings window and popup was shown and hidden: please see attachment.
-
Attachment: 1.txt
(Size: 109.60KB, Downloaded 272 times)
[Updated on: Sun, 16 November 2014 15:56] Report message to a moderator
|
|
|
|
|
Re: Drop list is not shown [message #43906 is a reply to message #43904] |
Sun, 16 November 2014 17:25 |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |
|
|
mirek wrote on Sun, 16 November 2014 19:39I do not see
DLOG("---------------------------");
DDUMP(popup->GetRect());
DDUMP(rt);
I've split log into 2 pieces.
The first piece was generated after I clicked drop list:
popup->GetRect() = [1130, 343] - [1347, 344] : (217, 1)
rt = [1130, 343] - [1347, 615] : (217, 272)
r0 = [1130, 343] - [1347, 344] : (217, 1)
The second *big* part (added as attachment) was generated after the settings window was closed.
If I'm not mistaken, the problem is with Rect for animation. As you see in log, this Rect is 1 pixel in height. This could answer why only black line is shown. But I don't really know why popup is correctly shown after all (when window is closed).
|
|
|
Re: Drop list is not shown [message #43907 is a reply to message #43905] |
Sun, 16 November 2014 17:28 |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |
|
|
MT really shouldn't be an issue here, but I have some heavy processing in main thread executed with SetTimeCallback. Until now it wasn't a problem.
Update: disabling this TimeCallback doesn't fix problem with popup.
[Updated on: Sun, 16 November 2014 17:32] Report message to a moderator
|
|
|
Re: Drop list is not shown [message #43908 is a reply to message #43906] |
Sun, 16 November 2014 17:47 |
|
mirek
Messages: 14105 Registered: November 2005
|
Ultimate Member |
|
|
Mindtraveller wrote on Sun, 16 November 2014 17:25mirek wrote on Sun, 16 November 2014 19:39I do not see
DLOG("---------------------------");
DDUMP(popup->GetRect());
DDUMP(rt);
I've split log into 2 pieces.
The first piece was generated after I clicked drop list:
popup->GetRect() = [1130, 343] - [1347, 344] : (217, 1)
rt = [1130, 343] - [1347, 615] : (217, 272)
r0 = [1130, 343] - [1347, 344] : (217, 1)
The second *big* part (added as attachment) was generated after the settings window was closed.
If I'm not mistaken, the problem is with Rect for animation. As you see in log, this Rect is 1 pixel in height. This could answer why only black line is shown. But I don't really know why popup is correctly shown after all (when window is closed).
Here r0 == popup->GetRect is initial position. It is that line you can see, but as initial position for the animation it is correct. "rt" is 'target position' - Animate is supposed to go from r0 to rt. So far so good.
Anyway, if you say that the second part (which looks like pretty correct animation being performed) is performed later, my guess is that the animation is somehow blocked until the dialog closes. It should be pretty simple to test, just put some logs on your closing action, some logs into Animate at exit....
One possible cause of this 'stalling' could be that some other thread keeps GuiLock locked (or starved).
Mirek
[Updated on: Sun, 16 November 2014 18:15] Report message to a moderator
|
|
|
Re: Drop list is not shown [message #43923 is a reply to message #43908] |
Wed, 19 November 2014 00:21 |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |
|
|
I've finally found the source of problem.
Second window turned out to be false path. It had nothing to do with dropping. After some testing it became clear that drop list failure doesn't depend on window, but it depend on whether specific control is shown in window. Right after control is hidden, all drop lists are fired one after another.
This control is just slightly customized version on Edit control with additional buttons. As later testing revealed, the problem was not with the control itself, but with custom Convert used in it. However I'll post code of this control just to show what I'm talking about:
class EditIntKeyless : public EditInt
{
public:
EditIntKeyless()
:convertChecker(this)
{
mbutton.AddButton().SetImage(IMG::b_minus).Width(23) <<= callback(this, &EditIntKeyless::OnDec);
mbutton.AddButton().SetImage(IMG::b_plus) .Width(23) <<= callback(this, &EditIntKeyless::OnInc);
AddFrame(mbutton);
SetData(1);
this->WantFocus(true);
SetConvert(static_cast<Convert &>(convertChecker));
}
void SetupChecker(ChannelChecker *c, int a)
{
convertChecker.SetupChecker(c,a);
convertChecker.Check(GetData());
}
virtual void SetData(const Value& data)
{
convertChecker.Check(data);
EditInt::SetData(data);
}
private:
void OnInc() {SetData( 1 + (int) GetData()); WhenAction();}
void OnDec() {SetData(-1 + (int) GetData()); WhenAction();}
MultiButtonFrame mbutton;
ConvertChecker convertChecker;
};
As you may see, this control supports some kind of "channel checker" (for us, it is not that important what is that) which gets control's pointer.
The problem arises when custom Convert considers control value invalid and tries to show it to user by calling Edit::Error. If you're interested, let's take a closer look at its source, it is short too:
class ConvertChecker : public ConvertInt
{
public:
ConvertChecker(EditField *_edit)
:checker(NULL)
,addr(-1)
,channel(-1)
,edit(_edit)
{}
void SetupChecker(ChannelChecker *c, int a) {checker = c; addr = a;}
public:
virtual Value Scan(const Value& text) const
{
Value chV = ConvertInt::Scan(text);
int ch = chV;
Check(ch);
return chV;
}
void Check(int64 c) const
{
if (channel >= 0)
UnregisterChannel(channel);
channel = static_cast<int>(c);
bool isFree = CheckChannel(channel);
if (channel >= 0)
RegisterChannel(channel);
//edit->Error(!isFree); // <-- this is the source of the problem!
}
private:
bool CheckChannel(int ch) const
{
if (!checker || addr < 0 || ch < 0)
return true;
return checker->IsChannelFree(addr,ch);
}
void RegisterChannel(int ch) const
{
if (!checker || addr < 0)
return;
checker->RegisterChannel(addr,ch);
}
void UnregisterChannel(int ch) const
{
if (!checker || addr < 0)
return;
checker->UnregisterChannel(addr,ch);
}
ChannelChecker *checker;
int addr;
mutable int channel;
EditField *edit;
};
Here we have edit->Error() call which makes all the problems. If commented, all the drop lists work flawlessly. I haven't looked deeper into U++ code, but it looks like erroneous state of control stalls any dropping animations in GUI.
I don't know if this is a bug or a feature, but it is certainly something to be documented (IMO).
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Fri Nov 01 01:37:10 CET 2024
Total time taken to generate the page: 0.03767 seconds
|
|
|