Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to handle GUI Events Correctly?  (Read 3182 times)

0 Members and 1 Guest are viewing this topic.

keyforge

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
How to handle GUI Events Correctly?
« on: June 16, 2011, 07:05:11 pm »
Hello, SFML Community!

My project I'm working on is http://www.mediafire.com/?12wf6lfvjwc3n6g. (You need MSVC++ 2010 Runtime to run it, Windows only ATM, sorry Mac and Linux!)

A little about my project: This is my first time writing a GUI and a game. I've written 95% of the engine by myself so I'm pretty happy how my first games turning out. It's only about 10% done at it's current state though. I wrote a game engine for it and most of my code is pretty clean other than a few hacks put in for testing. Please excuse my bad code if there's any. Game developing is exciting!

My Text Button Widget works OK but mess around with it with holding down and stuff and it has messed up hovering and `activation`. When held down or clicked it should be the darker gold color and when hovering only it should be selective yellow (the yellow on the Asteroids logo).

All widget events are handled by a Widget interface with virtual event functions and the widget event function is as follows:

Code: [Select]
void HandleEvents(sf::Event eEvent) {
if(eEvent.Type == sf::Event::MouseMoved) {
if(myGame->GetInput().GetMouseX() >= myPosition.x && myGame->GetInput().GetMouseX() <= myPosition.x + myDimensions.x && myGame->GetInput().GetMouseY() >= myPosition.y && myGame->GetInput().GetMouseY() <= myPosition.y + myDimensions.y) {
OnMouseOver(eEvent.MouseMove);
myHover = true;
}

if(myHover == true && myGame->GetInput().GetMouseX() <= myPosition.x || myHover == true && myGame->GetInput().GetMouseX() >= myPosition.x + myDimensions.x || myHover == true && myGame->GetInput().GetMouseY() <= myPosition.y || myHover == true && myGame->GetInput().GetMouseY() >= myPosition.y + myDimensions.y) {
OnMouseOff(eEvent.MouseMove);
myHover = false;
}
}

if(eEvent.Type == sf::Event::MouseButtonPressed) {
OnClickPressed(eEvent.MouseButton);
}

if(eEvent.Type == sf::Event::MouseButtonReleased) {
OnClickReleased(eEvent.MouseButton);
}

if(eEvent.Type == sf::Event::KeyPressed) {
OnKeyPressed(eEvent.Key.Code);
}

if(eEvent.Type == sf::Event::KeyReleased) {
OnKeyReleased(eEvent.Key.Code);
}
}


And my Text Button virtual function implementations are:

Code: [Select]

void Button_Widget::OnMouseOver(const sf::Event::MouseMoveEvent& bMove) {
if(!IsActivated()) {
myText.SetColor(sf::Color(255, 186, 0));
SetActivated(false);
} else {
myText.SetColor(sf::Color(218, 165, 32));
}
}

void Button_Widget::OnMouseOff(const sf::Event::MouseMoveEvent& eMove) {
myText.SetColor(sf::Color(192, 192, 192));

if(IsActivated()) {
SetActivated(false);
}
}

void Button_Widget::OnClickPressed(const sf::Event::MouseButtonEvent& eButton) {
if(IsHovering() && eButton.Button == sf::Mouse::Left) {
myText.SetColor(sf::Color(218, 165, 32));
}
}

void Button_Widget::OnClickReleased(const sf::Event::MouseButtonEvent& eButton) {
if(IsHovering() && eButton.Button == sf::Mouse::Left) {
myText.SetColor(sf::Color(255, 186, 0));
SetActivated(true);
}
}

void Button_Widget::OnKeyPressed(sf::Key::Code kKey) {
if(kKey == sf::Key::Return) {
SetActivated(true);
}
}

void Button_Widget::OnKeyReleased(sf::Key::Code kKey) {
if(kKey == sf::Key::Return) {
SetActivated(false);
}
}


If any of you know a better way to handle the events and hovering and activation please let me know! Thank you!
Need a place to upload your code, files or screenshots? Use SFML Uploads!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
How to handle GUI Events Correctly?
« Reply #1 on: June 17, 2011, 01:39:01 am »
The design looks okay. Depending on how flexible you want it to be, std::tr1::function might also be an option to implement callbacks instead of virtual OnXyz() functions. This is especially useful when you want the user of a button to register custom event listeners.

Concerning activation/hover issues, I would do it like this (don't think it is 100% correct, but you should get it). Well possible that there's a simpler solution, but not at that time of day ;)
Code: [Select]
if (MouseOverWidget())
{
if (!hover)
{
hover = true;
OnMouseEntered();
}

if (MousePressed())
{
active = true;
OnMousePressed();
}
else if (MouseReleased())
{
active = false;
OnMouseReleased();
}
}
else if (!MouseOverWidget() && hover)
{
hover = false;
OnMouseLeft();

if (active)
{
active = false;
OnMouseReleased();
}
}
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

keyforge

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
How to handle GUI Events Correctly?
« Reply #2 on: June 17, 2011, 01:42:54 am »
Thank you! Your approach seems much cleaner than mine. I will implement it and I think it's just what I need. Also, your Thor library is very nice! I'm not using it personally but I've tried it out and it's great to use!
Need a place to upload your code, files or screenshots? Use SFML Uploads!

Fouf

  • Newbie
  • *
  • Posts: 23
    • View Profile
How to handle GUI Events Correctly?
« Reply #3 on: June 17, 2011, 04:46:37 pm »
I know that rect's have a Contains(x, y) function, maybe make a Rect for each button, and then just have a function where you pass a rect and x and y and it does the check?
Code: [Select]
if(outline_rect.Contains(cords.x, cords.y))
{
activate();
}
- Fouf

 

anything