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

Author Topic: Thinking about making a GUI library  (Read 5040 times)

0 Members and 1 Guest are viewing this topic.

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« on: October 12, 2011, 08:42:46 pm »
Hey forum,

I'm playing around with the idea of making a GUI library.
I have some design decisions to make and I brainstormed a bit while I was at school. I have some questions though:

- Is using sf::Shape for drawing the boxes a good idea?

- And should I derive from sf::Drawable or make a
Code: [Select]
void draw(sf::RenderWindow* window) function?

- How could I stretch and shrink buttons if I'd use images. I know I could make one image part for the middle (which I can stretch) and one for the sides. Are there any other methods to do this?

- For event checking, what would be a better approach:
Code: [Select]
void checkEvent(const sf::Event& event) //which checks all the possibilites

Or

Code: [Select]
void onHover()
void onClick()


Which are to be called manually? I'm leaning more towards the first.

Thanks in advance.

PS: If it goes well, I'll ofcourse make it public so other users can benefit from it too :)[/code]

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thinking about making a GUI library
« Reply #1 on: October 12, 2011, 09:18:35 pm »
Quote from: "N1ghtly"
Is using sf::Shape for drawing the boxes a good idea?
If the functionality it brings is enough for you, then yes. For example you can't have textured shapes (yet), but if you don't need it, no problem. Color gradients are possible.

Quote from: "N1ghtly"
- And should I derive from sf::Drawable or make a
Code: [Select]
void draw(sf::RenderWindow* window) function?
Write a Draw() function. This offers more flexibility and you don't inherit all properties of sf::Drawable (like the blend mode). You should never use inheritance if it doesn't come with relevant advantages.

Quote from: "N1ghtly"
- How could I stretch and shrink buttons if I'd use images. I know I could make one image part for the middle (which I can stretch) and one for the sides. Are there any other methods to do this?
You can repeat textures instead of stretching them. You can calculate and pre-render them (using sf::RenderTexture).

Quote from: "N1ghtly"
- For event checking, what would be a better approach:
Code: [Select]
void checkEvent(const sf::Event& event) //which checks all the possibilitesOr
Code: [Select]
void onHover()
void onClick()
Which are to be called manually?
You should primarily care about the API, the implementation will be adapted to it. From my point of view as a user, callbacks are the most flexible way of binding GUI events (click, hover, etc.) to actions. There are classic Java ways, where you need to inherit from certain classes and override virtual functions. The C++ approach would use function objects (maybe combined with Boost.Function, Boost.Bind, Boost.Signals). You can read the Boost documentations to get an impression of the ideas.

And you learn really much when writing a GUI framework. It is quite complex, and you have to meet difficult design decisions when you want the API to be as user-friendly as possible. However if you only write it to have a GUI framework, you had better use one of the existing GUIs for SFML. SFGUI looks very promising. I began to write a GUI a long time ago, too -- it really takes a lot of time, don't underestimate it. I haven't developped it further since last year, because it would have required a huge amount of time to make it really flexible, which I preferred to invest in the development of Thor.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #2 on: October 12, 2011, 10:27:21 pm »
Wow thanks for the awesome input Nexus :)
I decided to store a sf::FloatRect in the class.
Drawing:
Code: [Select]
void Draw(sf::RenderWindow* window)
{
    window->Draw(sf::Shape::Rectangle(box, fillColor, 3, outlineColor);
}


I've never worked with callbacks before, but it looks good :)
How would they work?
I store a function pointer in the object, and when (in checkEvent(const sf::Event& event) ) it detects that the mouse hovers over it, it calls it. Right?

I feel I'm going to learn so much from this :D[/code]

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #3 on: October 13, 2011, 07:59:25 pm »
I'm stuck! I can't figure out how to set a member function as a callback...
A normal function works perfectly:

I use typedef boost::function<void ()> callback.
But when I call my setCallback function with a member var it doesnt compile...

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Thinking about making a GUI library
« Reply #4 on: October 13, 2011, 08:43:35 pm »
Quote from: "N1ghtly"
I store a function pointer in the object, and when (in checkEvent(const sf::Event& event) ) it detects that the mouse hovers over it, it calls it. Right?
Yes.

Quote from: "N1ghtly"
But when I call my setCallback function with a member var it doesnt compile...
You have to use boost::bind(), see its documentation.

By the way, function and bind are also in namespace std (if you have a C++11 standard library) or std::tr1.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Thinking about making a GUI library
« Reply #5 on: October 14, 2011, 12:42:40 am »
Quote from: "Nexus"
Quote from: "N1ghtly"
- And should I derive from sf::Drawable or make a
Code: [Select]
void draw(sf::RenderWindow* window) function?
Write a Draw() function. This offers more flexibility and you don't inherit all properties of sf::Drawable (like the blend mode). You should never use inheritance if it doesn't come with relevant advantages.

On the other hand, deriving from sf::Drawable provides many benefits:

- Within your widget, every graphic component’s position is relative to the widget position. So if you want to move your widget, you just need to update the Drawable position, and graphic components drawn in the Render method will be moved automatically.
- sf::Drawable properties are very useful: beside obvious ones such as Position and Size, I do believe that features such as blend mode, rotation and scale (zoom) could be used in a GUI system, especially in a game GUI, where "eye-candies" are always welcomed.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Thinking about making a GUI library
« Reply #6 on: October 14, 2011, 12:48:13 am »
Your have good points. However in SFML 2, sf::Drawable is not going to remain in its current form. There will be sf::Transform to handle transforms (and thus relative positions).

See the new graphics API.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #7 on: October 14, 2011, 04:49:27 pm »
I tried with boost::bind() but I couldn't get it to work. I mean, I should pass an object and one of his functions to setOnClickCallback() right?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Thinking about making a GUI library
« Reply #8 on: October 14, 2011, 04:53:19 pm »
Quote from: "N1ghtly"
I tried with boost::bind() but I couldn't get it to work.
The Boost documentation contains many examples that show how the syntax should look like. Have you read it carefully?

You can use boost::bind() to bind an object and its member function (and even further parameters) together, so that they can be invoked like a normal function object.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #9 on: October 14, 2011, 05:36:38 pm »
Yes, but then it should be called like this:

Code: [Select]
button.setOnClickCallback(bind(&A::test, &testclass));

Do you think that would be acceptable?
Or I could overload the function, one which takes just a function, and one which takes an object and a function (and call boost::bind() inside that function)

It's just that I don't know how to write a function that takes an object and an object's function...

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Thinking about making a GUI library
« Reply #10 on: October 14, 2011, 06:11:40 pm »
Quote from: "N1ghtly"
It's just that I don't know how to write a function that takes an object and an object's function...


Code: [Select]
template<typename F>
void setOnClickCallback( F f )
{
    m_Callback = f;
}

template<typename T, typename F>
void setOnClickCallback( T* pInstance, F f )
{
    m_Callback = boost::bind( f, pInstance );
}


The single argument overload takes either function pointers or function objects. The two argument overload takes a class instance pointer as its first argument, and a member function pointer as its second.

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #11 on: October 14, 2011, 06:16:33 pm »
I tried it, but it doesnt work:

Code: [Select]
error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say '&A::test'|

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Thinking about making a GUI library
« Reply #12 on: October 14, 2011, 06:27:45 pm »
So do what the error message tells you. Say &A::test.

N1ghtly

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Thinking about making a GUI library
« Reply #13 on: October 14, 2011, 09:45:17 pm »
You don't understand, that means you can't pass the function...

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Thinking about making a GUI library
« Reply #14 on: October 14, 2011, 09:49:24 pm »
Show us your code, if possible complete and minimal. It is possible to pass member function pointers to boost::bind().
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: