Sign in to follow this  
WildJester

Menus - Problem with Dinput Mouse [LButton in state too long?!!]

Recommended Posts

Hello! I am making the menus for my game and have run into a problem. Ive spent a while trying to fix it so any help would be appreciated. I have a menu class which contains a std::vector<BUTTON>. the engine has a pointer to a menu called current menu. That is set to point to the current menu that i am on. That all works fine. The problem i have is that each button has a bounding box. The main menu has a button at say left = 5,top = 5, bottom = 10, right = 10. When that button is clicked, i goto a new menu. However, that menu also has a button at left = 5,top = 5, bottom = 10, right = 10. The same exact place. When i goto that menu, it still thinks i am hovered and clicking so it executes the second button as well! I tried timers, but that is a lame fix.. There must be something that i am doing wrong.. Below is the code.. Let me know if you have an idea!

bool BUTTON::isHovered()
{
	// check if the mouse intersects the current button
	if( PointInRect_Simple( Engine.mouse.getMousePos() ,this->boundingBox) )
		return true;
	return false;
}


bool BUTTON::isClicked()
{
 // if(  abs(((int)(GetTickCount()) - Engine.mouse.timeOfClick )) > 30 )
 //{
    //Engine.mouse.timeOfClick = (int)(GetTickCount());
  if (Engine.mouse.mouse_state.rgbButtons[0] & 0x80)
   return true;
 //}
  return false;
}


void updateMenuStatus()
{
  if( Engine.currentMenu->displayFlag == true )
  {
    for( int i = 0; i < (int)Engine.currentMenu->buttonVec.size(); ++i )
    {
      if( Engine.currentMenu->buttonVec[i].isHovered() )
      {
        // the current button is hovered..
        Engine.currentMenu->buttonVec[i].color =  D3DCOLOR_ARGB(200,0,250,200);
        

        if( Engine.currentMenu->buttonVec[i].isClicked() )
        {
          // current button is clicked.
          if( Engine.currentMenu->buttonVec[i].textureName == "Textures/Menus/newGameBut" )
          {
            Engine.LoadNewGame();
            Engine.currentMenu->displayFlag = false;
            return;
          }

          if( Engine.currentMenu->buttonVec[i].textureName == "Textures/Menus/optionsBut" )
          {
            Engine.currentMenu = &Engine.menuVec[1];
            Engine.currentMenu->displayFlag = true;
            return;
          }

          if( Engine.currentMenu->buttonVec[i].textureName == "Textures/Menus/backBut" )
          {
            Engine.currentMenu = &Engine.menuVec[0];
            Engine.currentMenu->displayFlag = true;
            return;
          }

          if( Engine.currentMenu->buttonVec[i].textureName == "Textures/Menus/quitBut" )
          {
            PostQuitMessage(0);
            return;
          }

        }
      }
      else
      {
        Engine.currentMenu->buttonVec[i].color =  D3DCOLOR_ARGB(255,255,255,255);
      }
    }
  }
}



Share this post


Link to post
Share on other sites
well i fixed it by adding the timer check around the other button check. I set the time each time the lbutton is pressed...

Even though it is fixed. If you guys know better ways, please let me know!!


if( abs(((int)(GetTickCount()) - Engine.mouse.timeOfClick )) > 30 )
{
if( Engine.currentMenu->buttonVec[i].textureName == "Textures/Menus/quitBut" )
{
PostQuitMessage(0);
return;
}
}

Share this post


Link to post
Share on other sites
Why is you isHovered() in your Button class? Because that is NOT the responsibility of the button class, to figure out if the mouse is inside it's rectangle.

Apart from that, it is also very inefficient to do it that way, because each control would have to call that. In a more efficient approach, your WindowManager class should do that. I would check if the mouse is within the client rect of a control, and if yes, check any child controls to see if that control is in there too.

This would reduce the amount of controls running this check significantly(Esp. if you have a total of 100 controls, residing in 3 windows. Because you'd only have to traverse those windows where the mouse is in).

Same account for the isClicked function. Your window manager should do the check on the button, and if the mouse button went from DOWN to UP again, and the cursor is over the same control as the it was on the DOWN, then you control should receive an OnClick event.

Also, you're better off ditching DirectInput and using WM_MOUSE messages. They are more accurate and actually support mouse acceleration, etc.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this