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++ Core » Animate does not really animate
Animate does not really animate [message #28565] Tue, 07 September 2010 13:25 Go to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Hello,

Lately, I was wondering why the GUIEFFECT_SLIDE produces such a flickering and messy effect, rather than a nice and smooth sliding.

The first thing I discovered, in the Animate function (CtrlLib.cpp), is that there is a grow/shrink factor calculated:
int q = 25 * t / 200

Now, since t is always <= 200, this q is always 0 except just before the loop is aborted. And, thus, no shrinking or growing is actually performed until the loop is aborted, because the 200msec are used up. After which the control is set to the target size. So actually, instead of a slide effect, there is just a delay of 200 msec and then the control gets the full target size.

I got a much smoother result by replacing the growing factor by the following code:
if(r.left > target.left)
   r.left -= ((r.left - target.left)* t) /200;
if(r.top > target.top)
   r.top -= ((r.top - target.top) * t) /200;
if(r.right < target.right)
   r.right += ((target.right - r.right) * t) / 200;
if(r.bottom < target.bottom)
   r.bottom += ((target.bottom - r.bottom) * t) / 200;
if(r.GetWidth() > target.GetWidth())
   r.right = (r.left + ((r.GetWidth() - target.GetWidth()) * t) / 200);
if(r.GetHeight() > target.GetHeight())
   r.bottom = (r.top + ((r.GetHeight() - target.GetHeight()) * t) / 200);

But, then there was something else: after the sliding effect, the popped control flashed once more. As far as I understand the code of the Drop procedure in controls like PopupTable, I guess the reason is that the popped up control is briefly removed and recreated. I wonder if that cannot be avoided. If not, one could use LockWindowUpdate on windows around this removing/recreating. I don't know if such a thing exists on other platforms.

Best regards,
frank

[Updated on: Thu, 09 September 2010 09:47]

Report message to a moderator

Re: Animate does not really animate [message #28624 is a reply to message #28565] Wed, 08 September 2010 13:39 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Hello again,

I managed to fix the second problem (the flash at the end of the animation) as well and now I have a very smooth experience in the popup using slide effect.
I may have overlooked something (remember; I am not so proficient in the Ultimate internals), but I modified a part of ColorPopup::Popup, like so:
/******
if(GUI_PopUpEffect()) {
   Ctrl popup;
   popup.Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));
   popup.SetRect(RectC(rt.left, rt.top, 3, 3));
   popup.PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP);
   SetFocus();
   Ctrl::ProcessEvents();
   Animate(popup, rt, GUIEFFECT_SLIDE);
}
SetRect(rt);
Ctrl::PopUp(owner, true, true, true);
**********/
if(GUI_PopUpEffect()) {
   //Ctrl popup;
   //popup.Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));
   SetRect(RectC(rt.left, rt.top, 3, 3));
   Ctrl::PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP);
   SetFocus();
   Ctrl::ProcessEvents();
   Animate(*this, rt, GUIEFFECT_SLIDE);
}
else
{
   SetRect(rt);
   Ctrl::PopUp(owner, true, true, true);
}

The commented out code is the original version and the rest is my modification. As you can see, my intention was to avoid the use of the separate control to do the popping up and use the control itself, directly.
I works like a charm and so, now, I wonder why this indirection is used in the Popup procedures of most (many/all?) controls?
If there is nothing wrong with this modification, could you please consider it for applying? It gives a much more pleasant user experience on Windows where sliding is in effect.

Best regards,
frank

PS: I used the new GridCtrlTest project to do my testing.
Re: Animate does not really animate [message #28655 is a reply to message #28565] Thu, 09 September 2010 12:43 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
frankdeprins wrote on Tue, 07 September 2010 07:25

Hello,

Lately, I was wondering why the GUIEFFECT_SLIDE produces such a flickering and messy effect, rather than a nice and smooth sliding.

The first thing I discovered, in the Animate function (CtrlLib.cpp), is that there is a grow/shrink factor calculated:
int q = 25 * t / 200

Now, since t is always <= 200, this q is always 0 except just before the loop is aborted.



Not true. You have missied 25 * ....

Quote:


I got a much smoother result by replacing the growing factor by the following code:



Only smoother because you have skipped

q *= q;

line... The idea there is that slide effect should accelerate, so longer lists get animated about as fast as shorter ones.

Anyway, maybe your approach, where we are always fixed time long is better...

Mirek

[Updated on: Thu, 09 September 2010 12:46]

Report message to a moderator

Re: Animate does not really animate [message #28657 is a reply to message #28655] Thu, 09 September 2010 14:38 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Yes, you are right, q is indeed only 0 as long as t < 8.
But the second issue (the flash at the end of the animation) bothers me more and I wonder what the reason is for using a separate control to do the animated popups. I managed to make it work without this extra control, but I am sure there must be some reason for this aproach.
Here is how I modified two Popup methods, resulting in less flicker:
void ColorPopUp::PopUp(Ctrl *owner, Color c)
{
	int cy = norampwheel ? 0 : 110;
	Size sz = AddFrameSize(18 * 16, GetCy() + cy);
	Rect wr = GetWorkArea();
	Rect r = owner->GetScreenRect();
	int x = r.left;
	int y = r.bottom;
	if(x + sz.cx >= wr.right)
		x = r.right - sz.cx;
	if(y + sz.cy >= wr.bottom)
		y = r.top - sz.cy;

	Rect rt = RectC(x, y, sz.cx, sz.cy);
	if(GUI_PopUpEffect()) {
		SetRect(RectC(rt.left, rt.top, 1, 1));
		Ctrl::PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP);
		SetFocus();
		Ctrl::ProcessEvents();
		Animate(*this, rt, GUIEFFECT_SLIDE);
	}
	else
	{
	SetRect(rt);
	Ctrl::PopUp(owner, true, true, true);
	}

	SetFocus();

	if(!norampwheel) {
		ramp.LeftPos(0, 18*7).VSizePos(GetCy(), 0);
		wheel.LeftPos(18*9 - 1, 18*7).VSizePos(GetCy(), 0);
	}

	ramp <<= c;
	wheel <<= c;
	color = c;
	colori = -1;
}

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;
	if (GUI_PopUpEffect()) {
		if(up) {
			SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom));
		}
		else {
			SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1));
		}
		Ctrl::PopUp(owner, true, true, GUI_DropShadows());
		SetFocus();
		Ctrl::ProcessEvents();
		Animate(*this, rt, GUIEFFECT_SLIDE);
		CenterCursor();
		open = true;
	}
	if (!open)
	{
		CenterCursor();
		SetRect(rt);
		Ctrl::PopUp(owner, true, true, GUI_DropShadows());
		SetFocus();
		open = true;
	}
	inpopup--;
}


PS: Thanks for applying the Animate changes. I saw you reduced the animation duration as well, and that's a good thing also; it didn't have to be that explicit.

Best regards,

frank

[Updated on: Sat, 11 September 2010 08:09]

Report message to a moderator

Re: Animate does not really animate [message #28683 is a reply to message #28657] Sat, 11 September 2010 20:11 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
frankdeprins wrote on Thu, 09 September 2010 08:38

Yes, you are right, q is indeed only 0 as long as t < 8.
But the second issue (the flash at the end of the animation) bothers me more and I wonder what the reason is for using a separate control to do the animated popups.



Found the original reason - scrollbar (gets displayed during animation). Also, the effect in DropList is not equivalent to what is standard in other platforms - it should slide in, not be gradually revealed..

Anyway, I am not quite happy about those visual artifacts, so I guess we should fix that...

[Updated on: Sat, 11 September 2010 20:21]

Report message to a moderator

Re: Animate does not really animate [message #28687 is a reply to message #28683] Sat, 11 September 2010 21:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, I believe I have found a way how to fix it - commited.

If you have got a bit of time, please check if all is OK (ideally both code and behaviour).

Besides PopUpTable and ColorPopUp, I have also fixed DropTree.

Mirek
Re: Animate does not really animate [message #28693 is a reply to message #28687] Sun, 12 September 2010 10:44 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Hello Mirek,

Thanks for looking at the Popup code.
I had indeed also noticed the difference of my Popup method with the older one, in the visibility of the scrollbars. I did not find this disturbing, though; especially not, when compared to the flashing. But if it can be avoided, then it is indeed even better. I assume that is what the
        AutoHideSb(false);
        HideSb(true);
...
        HideSb(false);
        AutoHideSb(true);

code is meant for.
But I do not understand why there still is this separate popup control (albeit of a new specialized struct type). Because, as I can see it, this still introduces more flicker than the method I used without it. To let you be the judge of it, I include two executables; the 2686 version is with your new code (literally, as taken from the repository), the 2678 version is with the old popup code, modified as I suggested. I use Vista and I can still see a difference in the smoothness of the popup of the colorpopup in the 'Property Grid' tab.
Is this separate control intended to fix your remark:
Quote:

Also, the effect in DropList is not equivalent to what is standard in other platforms - it should slide in, not be gradually revealed.
?


Best regards,

frank

PS: There is a little difference in look of the DropList compared to the native combobox (in list only/non-editable mode) in Windows. In Windows; the 'button' has a 'pressed' look as long as the list is visible; even when the mouse is not even hovering over the button anymore.

[Updated on: Sun, 12 September 2010 11:26]

Report message to a moderator

Re: Animate does not really animate [message #28698 is a reply to message #28693] Sun, 12 September 2010 20:50 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
frankdeprins wrote on Sun, 12 September 2010 04:44

Hello Mirek,

Thanks for looking at the Popup code.
I had indeed also noticed the difference of my Popup method with the older one, in the visibility of the scrollbars. I did not find this disturbing, though; especially not, when compared to the flashing. But if it can be avoided, then it is indeed even better. I assume that is what the
        AutoHideSb(false);
        HideSb(true);
...
        HideSb(false);
        AutoHideSb(true);

code is meant for.
But I do not understand why there still is this separate popup control (albeit of a new specialized struct type).



Incorrect, the popup is same, but I overlay another widget over it with the same content.

Quote:


Quote:

Also, the effect in DropList is not equivalent to what is standard in other platforms - it should slide in, not be gradually revealed.
?



Simply speaking, with droplist, the last line is always visible through the animation and "goes down", makes impression the the list slides down from top.

Please, check windows droplists to see the difference.

Also, in the code, notice:

Ctrl::Add(pb.BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));

"BottomPos". That is the reason to introduce more complex code there..

[Updated on: Sun, 12 September 2010 20:51]

Report message to a moderator

Re: Animate does not really animate [message #28701 is a reply to message #28698] Mon, 13 September 2010 07:59 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Hello Mirek,

I can understand this very well and fully agree with it; I just wonder if the same effect (the sliding in) cannot be obtained by offsetting the drawing origin and shifting it along with the growing of the control. Without overlaying another control.

Best regards,
frank
Re: Animate does not really animate [message #28714 is a reply to message #28701] Mon, 13 September 2010 18:07 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
frankdeprins wrote on Mon, 13 September 2010 01:59

Hello Mirek,

I can understand this very well and fully agree with it; I just wonder if the same effect (the sliding in) cannot be obtained by offsetting the drawing origin and shifting it along with the growing of the control. Without overlaying another control.

Best regards,
frank


That would be possible, but would require substantial support in all concerned widgets.

I believe that this way the result should be exactly the same. For windows, it is no difference, as there is just single HWND involved, single WM_PAINT message with or without the overlay control. And in the end phase, it is just just the same as repainting the area with the same content.

If you still see any difference, we will have to search elsewhere.
Re: Animate does not really animate [message #28721 is a reply to message #28714] Mon, 13 September 2010 20:58 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
No, I have the impression the behaviour is indeed the same as it is on Windows. Besides, that was not the reason I kept on nagging Smile ; it's just that I have the impression that it introduces a tiny bit of flickering. But I can live with that.

Best regards,
frank

[Updated on: Mon, 13 September 2010 21:01]

Report message to a moderator

Re: Animate does not really animate [message #28790 is a reply to message #28721] Thu, 16 September 2010 23:51 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
frankdeprins wrote on Mon, 13 September 2010 14:58

No, I have the impression the behaviour is indeed the same as it is on Windows. Besides, that was not the reason I kept on nagging Smile ; it's just that I have the impression that it introduces a tiny bit of flickering. But I can live with that.



Actually, if you feel like you want to investigate, you are welcome. There might be something I have missed.... No reason no to be perfect Smile
Re: Animate does not really animate [message #28984 is a reply to message #28790] Thu, 30 September 2010 13:16 Go to previous messageGo to next message
frankdeprins is currently offline  frankdeprins
Messages: 99
Registered: September 2008
Location: Antwerp - Belgium
Member
Hello Mirek,

I have done some experimenting and came to some simple change that gives me the impression that it improves the smoothness of the dropdown. Based on code inspection, it may hold sense.
I made next change in PopupTable:
...
NoCursor(true);
sPaintRedirectCtrl pb;
if(up) {
    SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom));
    pb.ctrl = this;
    Ctrl::Add(pb.TopPos(0, rt.Height()).LeftPos(0, rt.Width()));
}
else {
    SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1));
    pb.ctrl = this;
    Ctrl::Add(pb.BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));
}
Ctrl::PopUp(owner, true, true, GUI_DropShadows());
SetFocus();
...
CenterCursor();
NoCursor(false);
...
As you see, I moved the statement
pb.ctrl = this;
after the initial sizing of the control that is about to popup/dropdown. I assume this prevents the control from showing up briefly in some default size. Also, I hide the cursor while animating.
Anyway; I would appreciate your opinion.

Best regards
frank

[Updated on: Thu, 30 September 2010 14:15]

Report message to a moderator

Re: Animate does not really animate [message #29089 is a reply to message #28984] Mon, 04 October 2010 21:14 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Very unlikely, in fact, nothing should be drawn until "Animate"...
Previous Topic: no true Iterator support in Upp???
Next Topic: How to init StreamString
Goto Forum:
  


Current Time: Mon Apr 29 13:54:45 CEST 2024

Total time taken to generate the page: 0.02859 seconds