how to define actions of a "Button" class?

hello,

i'm wondering how actions of a "Button" class would be defined. the class is only one, but each object will act differently when clicked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Button{
private:
  float position_x, position_y;
  std::string label;

public:
  Button();
  ~Button();
  void onClick();
};

Button new_document_button;
Button open_document_button;
Button exit_button;
//etc 


also, i think many return types for the onClick() function would be possible. it all depends on what a specific button should do. so i'm really curious about this.
thanks in advance :)
Look up Polymorphism, as it is exactly what you want here. You will need to rethink your idea about "multiple return types" however.
Last edited on
you mean i should create many derived classes, each one with a specific function? wouldn't that make me have more classes than objects in most cases (except when a gui uses all possible buttons)?

also, i did read something about std::function, but didn't really understood...

thanks in advance :)
By using the C++ standard library you already have more classes than objects, I don't understand why that is a concern of yours.

You can use an approach with std::function but it's effectively the same thing - it's not called a 'polymorphic function wrapper' for no reason ;p
you're right, i've never thought about that :P
i tried to use std::function anyway, just out of curiosity, but wasn't able to. is it possible to make an object that can change a string and another that can change an int if both are from the same class?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <functional>

class Button{

public:
  Button();
  ~Button();
  std::function<void(void)> action;
};

int ChangeInt(int my_int){
    return my_int+1;
}
std::string ChangeString(std::string str){
    return str+"_plus_something";
}

int main(){
    Button string_changer, int_changer;
    int my_int = 0;
    std::string my_string = "first_string";

    int_changer.action() = ChangeInt(int);
    string_changer.action() = ChangeString(std::string);

    std::cout << "int:" << int_changer.action(my_int);
    std::cout << "; string:" << string_changer.action(my_string);

    return 0;
}
Instead of using functions, use functors:

http://coliru.stacked-crooked.com/a/265e0af114ab03d1

std::function will call the function operator for objects that define it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Button{
private:
  float position_x, position_y;
  std::string label;

public:
  Button();
  ~Button();
  void onClick();
};

Button new_document_button;
Button open_document_button;
Button exit_button;
//etc  
Shouldn't your class have a bounding box of the button (left, top, width, height)? Otherwise that is going to be very hard to click on that one tiny pixel.
@giblit: Most modern graphics libraries let you get the width and height of a rendered string.
They also let you get the position of them. So why have part of it in the class? Anyways the actual image(sprite) of the button isn't even in the class so I am not sure how they would get the width/height of it. Well, I guess in this case it is text but still where is the actual "label" object to get the dimensions from? Is it created and stored in the constructor?

For a basic button class I would do something like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Button
{
    private:
        struct Rect
        {
            float x;
            float y;
            float width;
            float height;
        } rect;
        
        std::string label;
        
        bool isHovering(); //if it is hovering it can't enter since it already has entered,
        //if it is not hovering it can't exit since it is not already hovering
        bool wasPressed(); //if mouse was down pressed over the button then
        //it can't be pressed and released over the button
        sprite button; //the thing to be drawn
    public:
        Button();
        ~Button();
        
        void update(); //update and draw the button
        
        bool onMouseDown(); //mouse was clicked over button
        bool onMouseUp(); //mouse was released over button
        bool onMouseDownAndUp(); //mouse was clicked and released over button
        bool onMouseEnter(); //mouse entered the button
        bool onMouseOver(); //mouse is hovering over button
        bool onMouseExit(); //mouse left the button
};
Though, most graphics libraries already have a rect class.

I suppose you could add the "add action" or w.e delegate kind of thing to the buttons aswell.
Last edited on
the real class does have a bounding box. it is made in SFML, with a sf::Sprite, a texture reference, etc :P
i removed most of things just to make the class more readable in this forum.

anyway, i'll dig up a little more on functors, which seemed interesting . thanks everybody for the help :)
Topic archived. No new replies allowed.