Button hover refresh.. specific case

Discussion and support for general JUCE issues

Button hover refresh.. specific case

Postby wphantom » Wed May 16, 2012 10:12 am

Dear JUCE geeks,


I have a small "bug" in one of my porgram that I can't find a simple solution.

I have an image button with both normal image and an overImage.

When the mouse enter the button, the overImage is displayed. Then if the user clicks the button, my program needs to hide the button and reset the position of the mouse to the center of the screen;

A few seconds later I make the button visible again (the mouse was still at the screen center I.e. not over the button). But the button still shows the "overImage" instead of normal Image. then if the mouse is moved by the user, the button returns to the normal image.

I suspect a problem with the mouseexit not been called.
Code: Select all
CenterMouse(); // move louse to screencenter (outside button)
Rep1Button->setState(Rep1Button->buttonNormal ); //tried this but didn't worl
Rep1Button->repaint(); //tried this but didn't work
Rep1Button->setVisible(false);


When I do a Rep1Button->setVisible(true); the overImage is displayed until user move mouse.
How to avoid this ?


Thanks in advance for any help


Sylvain Clément
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Wed May 16, 2012 10:53 am

Interesting.. AFAICT it should be ok if you make the button itself invisible, but perhaps you're making its parent invisible?

Does it help if you add this line to the Button class?

Code: Select all
void Button::parentHierarchyChanged()
{
    updateState();

    Component* const newKeySource = (shortcuts.size() == 0) ? nullptr : getTopLevelComponent();
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Button hover refresh.. specific case

Postby wphantom » Wed May 16, 2012 2:37 pm

Thanks Jules for your answer.

unfortunately adding updateState(); in parentHierarchyChanged() did not solve the problem.

In my piece of code my Rep1Button is of type ImageButton* Rep1Button;


I did a little experiment.

Each time I want to change the visibility of the button I call this method

Code: Select all
void myclass::toggleResponseButtons(bool state)
{
   CenterMouse();
   Rep1Button->setState(Rep1Button->buttonNormal );Rep1Button->repaint();   
   Rep1Button->setVisible(state);   
}


at the begining of th eprogram the button is diplayed
When the user click on the button (and since the mouse entered the button area overImage was displayed) I call toggleResponseButtons(false)
and 5 seconds later (triggered with a Timer) I made a new call to toggleResponseButtons(true) to make the button visible again but with overImage displayed until the user moves the mouse.

The experiment : I did comment the last line of my toggleResponseButtons button as below :
Code: Select all
void myclass::toggleResponseButtons(bool state)
{
   CenterMouse();
   Rep1Button->setState(Rep1Button->buttonNormal );Rep1Button->repaint();   
   //Rep1Button->setVisible(state);   <Do not change visibility of the button
}


That was the only change in my program. At the 1st call to toggleResponseButtons(false) the button did not disappeared (of course) but it went back to the normalImage immediately.

Thus it seems that the setVisible(false) prevent the button from going back to the normalImage.

Any Idea ?


Sylvain
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Wed May 16, 2012 5:23 pm

When you make it invisible, Button::visibilityChanged gets called, which automatically updates the state based on the mouse, so there's no point setting the state explicitly yourself beforehand. Try calling setState *after* making it invisible, and you might have more luck!
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Button hover refresh.. specific case

Postby wphantom » Fri May 18, 2012 10:12 am

unfortunately it doesn't work...

S
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Fri May 18, 2012 10:51 am

Can you create a little test-case code snippet that I could paste into the demo app to reproduce this?
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Button hover refresh.. specific case

Postby wphantom » Fri May 18, 2012 3:15 pm

Thanks Jules,

I just reproduced the problem in jucedemo.


here the modifications I did in the DemoTabbedComponent class of "WidgetsDemo.cpp"

(1) add ", public Timer" to the declaration of the DemoTabbedComponent class.
(3) add :

Code: Select all
private:
   Button* LastButton;

at the bvegining of the DemoTabbedComponent class

(3) add the following at the end of the buttonClicked method :
Code: Select all
// Change mouse position, Hide the clicked button and wait 3s
      LastButton=button;
      CenterMouse();
      LastButton->setVisible(false);
      startTimer(3000);


(4) and add these tso methods (Center mouse will not really center the mouse in this exemple but it did in my app). :
Code: Select all
   void CenterMouse()
   {
      int w=this->getWidth();
      int h=this->getHeight();
      Point< int > target=this->getPosition();
      
      target.setXY( (int) target.getX()+(w/2),  (int) target.getY()+(h/2));
      
      Desktop::setMousePosition(target);
   }
   
   void timerCallback()
   {
      stopTimer();
      LastButton->setVisible(true);            
   }


Now run the demo go to the widget/button page

When you click on the second button (Image only drawable button) it will diseappear and the position of the mous will change. Just wait 3s and the button will reappear but with the "overImage" despite the fact thet the mouse is not over the button.

I did the test on Mac OSX 10.6.8...
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Fri May 18, 2012 3:21 pm

Ok... Before I try it, does this only happen if you keep the mouse completely still? Because Desktop::setMousePosition will not generate any mouse-move events (all OSes work that way: they just move the visible cursor, and never act as if the user moved it), so until you actually move the mouse, you can't really expect anything to get updated.
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Button hover refresh.. specific case

Postby wphantom » Fri May 18, 2012 3:54 pm

Code: Select all
does this only happen if you keep the mouse completely still?

Yes. if the user moves the mouse after the mouse center, the button goes to "normalImage".


Because Desktop::setMousePosition will not generate any mouse-move events

that is probably the good explanation except that it is then strange to observe the expected behavior in my modified example where I bypass the seVisible(false). Even with no user-initiated mouse movements, the button returns to the normalImage.


Code: Select all
void myclass::toggleResponseButtons(bool state)
{
   CenterMouse();
   Rep1Button->setState(Rep1Button->buttonNormal );Rep1Button->repaint();   
   //Rep1Button->setVisible(state);   <Do not change visibility of the button
}



Anyway, is there any mean to force the update or if it is possible to simulate a user mouse movement ?

S
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Fri May 18, 2012 4:14 pm

This really is a particularly edgy edge-case!

Until the mouse moves, the app will still see it at its old position inside the button, so I think everything is behaving perfectly "correctly". AFAIK there's no way to force a mouse-move via the OS (OSes make that difficult, probably for security reasons).

Have you tried Component::sendFakeMouseMove?
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Button hover refresh.. specific case

Postby gekkie100 » Sun May 20, 2012 7:32 pm

Maybe disabling the button before you hide it would work? Wouldn't it ignore the mouse when disabled?
gekkie100
JUCE UberWeenie
 
Posts: 249
Joined: Tue Apr 12, 2005 2:35 pm

Re: Button hover refresh.. specific case

Postby wphantom » Tue May 22, 2012 10:26 am

gekkie100 wrote:Maybe disabling the button before you hide it would work? Wouldn't it ignore the mouse when disabled?


Unfortunatelyit doesn't work. However I have tried to disable the component INSTEAD of hiding it.... thus my toggleResponseButtons became :


Code: Select all
void myclass::toggleResponseButtons(bool state)
{
   CenterMouse();
  Rep1Button->setEnabled(state);
}


And guess what ? It works. Not the ideal situation for me since the buttons are still slightly visible (the software is targeted at aged people) but I think I can deal with it...

Remark : if I add "Rep1Button->setVisible(state);" at the end of the method (after the seEnabled) then The problem reappears... The execution of setVisible seems to block the update of the button status. Quite strange. One alternative solution may be to wait a little before the set visible...


Sylvain Clément
wphantom
JUCE Geek
 
Posts: 29
Joined: Thu Mar 15, 2007 7:02 pm
Location: Lille, France

Re: Button hover refresh.. specific case

Postby jules » Tue May 22, 2012 11:01 am

Have you tried just deleting the button and creating a new one when it comes back?
User avatar
jules
Fearless Leader
 
Posts: 17217
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK


Return to General JUCE discussion

Who is online

Users browsing this forum: No registered users and 3 guests