GuiButton()s - Hover detect

I am still struggling to replace gfx buttons with the new Gui functions.

When a button is hovered over and changes color can I detect this to pop up a Help Tip, do some pre-processing, or change the chart? Yes, I read the posts, but can’t find a clear answer/solution.

I know that, assuming we have some refreshes (note that I refrain from mentioning the dreaded function :wink: ) this can be done with some additional code, but is there a way to wrap or enhance the GuiGetEvent() to provide this information - perhaps selectively?

thanks!
Herman

The Gui functions handle hover automatically (there is a "hover" color definable that is handled totally automatic without chart refresh and without formula execution). All this is done in very low-resource consuming fashion. And the entire purpose of Gui controls is NOT to trigger entire chart refreshes.

// hover demo - it highlights the button on hover
// without need for whole chart refresh

GuiButton( "test", 1, 10, 10, 100, 100, 0 );

GuiSetColors( 1, 1, 1, colorWhite, colorBlack, colorRed, 
colorWhite, colorBlue, colorRed, 
colorYellow, colorOrange /*hover colors*/ );

hoverdemo

Thanks you Tomasz, I knew that and that works great.

My question was: what would be the best way to detect GuiButton hover conditions - even if there is a performance penalty. I know how to do this in gfx/refreshes but perhaps there is a way to take advantage of the already existing GuiButtons to do this more efficiently.

We have hover detect in windows applications (including AB) using similar functions, right? (remember I am a non-programmer!)

Herman

As GuiButtons handle hovering visual effects internally they just don’t send hover (mouse enter/mouse leave) notifications to your formula and don’t trigger execution of your formula. This is by design.

If you want to create UIs that change on mouse move all the time you need to use low-level Gfx functions and RequestMouseMoveRefresh

1 Like

Thank you!

Have a great day,
Herman

I have noticed that in my case on Win 7 64 Bit (AmiBroker 32 bit) RequestMouseMoveRefresh() refreshes the chart many times per second when the mouse is moving (as expected), but about twice per second when the mouse is not moving at all.

In case of Win Vista 32 Bit (I know it’s obsolete) RequestMouseMoveRefresh() refreshes the chart many times per second even if the mouse is not moving.

In both cases there weren’t any RequestTimedRefresh() present in the code and I was checking it using local database (offline) - all other charts were refreshed only when clicked. I was using 1) _TRACE() and 2) Tools --> Preferences --> Miscellaneous–> “Display chart timing” to confirm that.

What might be the reson for this? If I understand correctly, when using RequestMouseMoveRefresh() the chart shouldn’t be regurarly refreshed when the mouse is not moving.

Regards.

I am not getting ANY refreshes if mouse does not move with this:

StaticVarAdd("refr",1 ); 
Title = Now() + " Refresh Cnt: " + StaticVarGet("refr");
RequestMouseMoveRefresh();

In other words it stays constant if mouse does not move.

mousemove

You will get one extra refresh when mouse stops moving for data tooltip when it pops (if you have this enabled).

Hello
I can confirm that on win7 x64
Ami_x32bit ver.6.21.0 is Not refresh, if we don’t move the mouse

Ami_x64 bit ver6.25.0 the refreshing running continuously if we just leave the mouse Only ON that specific chart.

Tested with afl that Tomasz just posted

No mouse move -> No refreshes on 6.25 x64, see the video:

mousemove625

You need to keep in mind that this is on LOCAL database. If you are using real-time streaming data source it will auto-refresh every second or so (even if market is closed).

Tomasz Yes that is true is not refreshing

For just to help… i have to say that i had 3 charts open, on LOCAL database
Only ONE of the 3 charts has just one Guibutton, (and was in seperate chart. and not on the refreshing testing afl)
And since i close the chart with the Guibutton the continuously refresing is stops so all good now :smiley:

1 Like

Thanks for this info. Apparently owner draw button is causing that. As soon as you remove GuiSetColors (which sets owner draw style) it won’t cause “no move” refreshes. Interesting, yet another Win ‘feature’ to check.

1 Like

I have just come to the same conclusion. With the GuiSetColors() in the example below the chart is refreshed like crazy :wink: even if the mouse doesn’t move. If this line is commented, these refreshes are no longer present.

StaticVarAdd( "refr", 1 );
Title = Now() + " Refresh Cnt: " + StaticVarGet( "refr" );
RequestMouseMoveRefresh();

GuiButton( "Test", 1, 20, 30, 50, 20, 10 );
GuiSetColors( 1, 1, 0 ); // default look

id = GuiGetEvent( 0, 0 ); event = GuiGetEvent( 0, 1 );

if( id == 1 && event == 1 ) Say( "Test" );

As it turns out, sometimes Windows sends artificial WM_MOUSEMOVE messages even if mouse did not move https://blogs.msdn.microsoft.com/oldnewthing/20031001-00/?p=42343/#55109

for example if you temporarily disable draw with SetDraw (False) and re-enable it, Windows will send mouse move “out of the blue”.

6.26 will account for that and won’t trigger refreshes even if Windows lies about mouse movement sometimes.

By the way this Old New Thing blog is hilarious :slight_smile: apparently I share “social skills of thermonuclear device” :slight_smile: with Raymond https://blogs.msdn.microsoft.com/oldnewthing/20121106-00/?p=6163

1 Like

That’s great :+1:

Tomasz, sorry for coming back to this - it won’t happen again :smiley: but maybe you consider allowing the user to limit the maximum refresh rate of RequestMouseMoveRefresh(). You already wrote, that it is smart and takes into account many factors - not to slow down the system, but even if the user has a powerful machine easily allowing 50 refreshes per second, why forcing so many refreshes if 5 or even 10 times less is enough? This function is really useful and there are many possible applications. Some formulas may require a lot of interaction for a longer period of time and (for many different reasons) it may be beneficial not to force those unnecessary refreshes.

Regards

In Amibroker we can do anything, right? Well, I thought so and gave it a try.

Here is a prototype GuiButton() that returns hover information. Please tell me what is wrong with this approach.

It seems to work fine if you do not mover your mouse too fast (perfectly OK for popups and the like). You can make the borders a little wider to obtain better hover detection.

I surround the GuiButton with a small gfx border and reduce the GuiButton by the same amount. Since, when you hover over a GuiButton the gfx values are frozen you can use this to detect when you enter the button area. Sorry I don’t have the time right now to polish up this code but hopefully some of the experts on this list can suggest improvements. For example why I had to fudge the x-y values to fit the overlay.

function xGuiButton( Label, ButtonID, x1, y1, width, height, notifyflags )
{
    global border, cx, cy;

    GfxSelectPen( colorred, border );
    GfxSelectSolidBrush( colorLightGrey );
    x2 = X1 + width;
    y2 = y1 + height;
    GfxMoveTo( x1, y1 );
    GfxLineTo( x2, y1 );
    GfxLineTo( x2, y2 );
    GfxLineTo( x1, y2 );
    GfxLineTo( x1, y1 );
    GuiButton( "TEST", TestID = 1, x1 + border, y1 + border, width - border - 1, height - border - 1, 7 );
    OverButton = cx >= x1 AND cx <= x2 AND cy >= y1 AND cy <= y2;
    return Overbutton;
}

RequestMouseMoveRefresh();
width = 200;
height = 50;
Border = 1;
x1 = 50;
y1 = 100;
cx = GetCursorXPosition( 1 );
cy = GetCursorYPosition( 1 );

Hover = xGuiButton( "TEST", TestID = 1, x1 + border, y1 + border, width - border, height - border, 7 );

GuiSetColors( 1, 1, Border,
	     /* Text, Back, Border  */
              colorblack, colorlightgrey, colorblack, 	
              colorblack, colorbrightGreen, colorblack, 	// Select
              colorwhite, colorblue, colorblack );		// Hover

if( Hover ) GuiSetText( "HOVER", TestID );              


Title =
    "CursorXposition = " + cx + "\n" +
    "CursorYPosition = " + cy + "\n" +
    "          Hover = " + Hover;

I would not say that it is “wrong”, but you are already aware of limitations/issues, like this:

plus it does this refreshes which Gui framework deliberately wants to avoid.

The thing that I am trying to communicate but apparently I am not able, is that it is better idea NOT to do actions on hover at all. Hovering “visual effect” is nice but it is meant as UI visual sugar only. In Windows hovering does NOT do anything but highlighting. No actions are triggered by hover and it is so for purpose. For example if you have TOUCH screen, there is NO hovering. All you get is a “click” if you touch. If you design UI that use hovering for actions then it will NOT work on touch screens.

Thank you Tomasz, I always appreciate your comments.

The fact of life is that many, even some experts, love to add a little sugar to their designs. When I demo an animated program it blows peoples mind - if nothing happens and they only hear a click they yawn and reach for their coffee. Real-Time trading requires a huge amount of patience; something to look at and keep you awake is nice :slightly_smiling_face:

Animated screens, count down timers, live bar charts, charts that are reconfigured on the fly (hover), help-popups, dynamic button layouts, drag features, etc. are fun to develop and also give you the reward of impressing someone. Performance awareness is essential to prevent problems, however, within the hardware restraints, adding a little sugar is worth it.

Also, almost all sugar-coating can be done conditionally so that during critical tasks they are disabled.

BTW, is it possible to know when a refresh is a mouse-refresh, something like Status( “MouseRefresh” )?

Best regards,
Herman

I can’t help but comment on touch screens… they are awfully slow and reduce the screen input resolution a hundred fold. I cannot imagine anyone using them for software development, trading, or any task the requires productivity. The turtle-style input dulls the brain and promotes premature aging. Give me a good mouse anytime!

Have a great day,
Herman

1 Like