Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - texus

#1411
Help requests / Re: Draggable Panel
08 April 2014, 20:59:43
QuoteAre there options I didn't see?
I don't see another option either.

Quote3. Make child windows transparent and disabled when not in moving mode. Unfortunately when transparent, the child window (logically) makes its contents transparent too.
There are of course workarounds to avoid making the whole contents transparent (without having to reset the transparency of every single widget in the window). You could have a panel inside the child window and all widgets inside the panel. Then after setting transparency of the child window to 0, you just set the panel to transparency 255 again.
But disabling the child window will also disable the widgets inside it, so this might not even be an option.

Quote1. First idea was panels, but they can't be moved around without me doing stuff with them, and I'd rather just do solution 4 than have to deal with panels that overlap, are invisible, and or are disabled.
If you would use a slightly edited version of the code in Container::mouseOnWhichWidget then it shouldn't be much of a problem. But unlike my suggestion before which didn't handle overlapping, you have to call the code twice: once to find out on which panel the mouse is on, and then on the widgets inside the panel to check if the mouse is on them. The code in that function also takes care of ignoring the invisible and disabled widgets.

But whatever way you choose, it will always be kindof a hack.
#1412
Help requests / Re: Draggable Panel
08 April 2014, 09:39:10
This is not yet available, you will have to implement this yourself.

The simpelest way to check if the mouse is on top of the panel and not on top of any of its widgets is with the mouseOnWidget function:

// Do this when the mouse goes down
if (panel->mouseOnWidget(x, y)
{
    bool mouseOnAnyWidget = false;
    for (auto& widget : panel->getWidgets())
    {
        if (widget->mouseOnWidget(x - panel->getPosition(), y - panel->getPosition()))
        {
            mouseOnAnyWidget = true;
            break;
        }
    }

    // If mouseOnAnyWidget is false here then you should start dragging the panel, until you get a mouse released event
}


This code has a few limitations:
- There should not be an overlapping widget in front of the panel
- The widgets inside the panel should not be overlapping
- Invisible and disabled widgets will react on this code

If you need to work around the second or third limitation (if you use invisisible or disabled widgets, or if widgets in your panel overlap) then just have a look at this code: https://github.com/texus/TGUI/blob/master/src/TGUI/Container.cpp#L1267 (the function is private, but you can almost literaly copy the code.
#1413
I deliberatly left this option out, because when handing the events, the gui won't know about these states. (read: I once added it but then I noticed that it didn't work so I removed it again)

I haven't looked yet at the changes you made, but when scaling like that you should notice that although the gui gets scaled correctly, the mouse events (e.g. button changing color on mouse hover) will still happen as if the gui wasn't scaled, thus when the mouse is on the wrong position.
Does it actually work with your changes?

What you want is probably to change the view. When passing 'false' to gui.draw and gui.handleEvents, they will use the current view from the window. So if you set the view to twice as small, the gui will appear twice as big.
#1414
Help requests / Re: Set View problem
05 April 2014, 10:52:43
The gui.draw function takes care of the rendering and the gui.handleEvent function takes care of sending the events to the widgets and making them respond in the right way.

So if you tell the draw function to use a different view then you should also give this view to handleEvent.
gui.handleEvent(event, false);

Also make sure that the same view is set at the moment the draw function is called and at the moment handleEvent is called. But this doesn't look like a problem in your minimum code.
#1415
QuoteSo, i must try to compile sfml with my compiler?
You can try it. But if you really downloaded the SJLJ version and the compiler used by codeblocks is still the correct one then it isn't going to make a difference.

QuoteI noticed, that the app requires at once libgcc_s_dw2-1.dll and libgcc_s_sjlj-1.dll. How he can require two different libraries at once?
I never had this problem, so I can only guess. You have three things: the code that you compile yourself, the sfml libs and the tgui libs. I would except that one of these is compiled with the wrong compiler.

But I would expect linking errors when you are using a library that is compiled agains the wrong compiler version. So maybe the sfml and tgui dlls that you have next to your exe are wrong while the .a files are the right ones. You can also try static linking, if the problem is with the dlls then this will work.

Anyway, perhaps you should send me the full project (e.g. on dropbox), including the sfml and tgui libraries and dlls. That way I can try replacing some of these files with versions on my pc and perhaps discover where the mistake is.
#1416
QuoteI get the same error, but the procedure is gxx_personality_sj0
These kind of errors mean that the libraries aren't compatible with the compiler as far as I know.
But it seems like one part tries to use gxx_personality_v0 (dwarf2?) and another part gxx_personality_sj0 (sjlj?).

Did you compile sfml yourself as well (with the same compiler)?

Perhaps you can try with the tgui precompiled libraries. It also includes the sfml libraries, so you'll be sure that the libraries are compatible. And they has been tested with MinGW 4.7.1-TDM.
#1417
Then you might have the dll from the wrong MinGW version.

You should check which compiler is being used to compile tgui and your project.
In CMake check the 'Advanced' option and have a look at which compiler is being used.
Also have a look at you codeblocks settings and look at which compiler it uses.
These should be the same folder, and it has to be the folder from where you copied the libstdc++-6.dll from.

Also, what happens if you don't put that dll next to the exe?
#1418
Did you by any chance copy libstdc++-6.dll next to your executable? (I think I've seen this problem before when someone copied the wrong libstdc++-6.dll next to its program)

Do you have multiple MinGW compilers on your pc?
#1419
Help requests / Re: MenuBar Item bindCallback
29 March 2014, 15:42:30
Quote from: Strikerklm96 on 29 March 2014, 15:22:36
menu->bindCallbackEx(std::bind(&MyClass::function, &mc), tgui::MenuBar::MenuItemClicked);
Doesn't work. Gives errors in "functional" file.
I changed the code a few times while writing the post, I must have overlooked that line. The function that bindCallbackEx needs has the Callback parameter, so it should have been
menu->bindCallbackEx(std::bind(&MyClass::function, std::placeholders::_1, &mc), tgui::MenuBar::MenuItemClicked);

Quote from: Strikerklm96 on 29 March 2014, 15:22:36
I looked at the documentation of TGUI though, and realized this:
menu->bindCallbackEx(&MyClass::function, &mc, tgui::MenuBar::MenuItemClicked);
does work
This function was added to just call the other one with the std::bind as parameter. Its just a shortcut so that you don't need to use std::bind and std::placeholders yourself.

Quote from: Strikerklm96 on 29 March 2014, 15:22:36I don't really understand what bind does though, and I have never learned this lambda stuff (is it something I should know?)
Bind is less important. It just binds a parameter to a function, so that where the function is stored it has no idea about the extra parameters, but they will be there when the function is called. Due to the way c++ works behind the scenes you need this for member functions as they actually have 'this' as argument.

But lambda functions are more important, they allow you to write nameless functions.
Here is a simple use case: the button will hide itself when it is clicked.
button->bindCallback([=](){ button->hide(); }, tgui::Button::LeftMouseClicked);

It replaces the following code:

void function()
{
    // Assuming that this function somehow manages to access the button,
    // which the lambda function could do without problems as it was in the correct scope
    button->hide();
}

button->bindCallback(function, tgui::Button::LeftMouseClicked);


Using lambda functions really starts to pay off when you need a simple functor (e.g. as last parameter in std::remove_if).

But in the end, you can perfectly work without them. But they may be interesting to look at someday.
#1420
Help requests / Re: MenuBar Item bindCallback
29 March 2014, 10:25:16
You will have to bind your own function that handles which item has been clicked.

The example becomes a little bit harder as the function needs to have access to the window, which is only possible if they are in the same class.
class MyClass
{
public:
    void function(const tgui::Callback& callback);
    sf::RenderWindow window;
}

void MyClass::function(const tgui::Callback& callback)
{
    if (callback.text == "Exit")
        window.close();
    /* else ... */
}

MyClass mc;
menu->bindCallbackEx(std::bind(&MyClass::function, &mc), tgui::MenuBar::MenuItemClicked);


You can also give the function the window as parameter, but then of course it will also have this window parameter even when you aren't handing the "Exit" callback.
void function(const tgui::Callback& callback, sf::RenderWindow& window)
{
    if (callback.text == "Exit")
        window.close();
}

menu->bindCallbackEx(std::bind(function, std::placeholders::_1, std::ref(window)), tgui::MenuBar::MenuItemClicked);


I guess the lambda function would perhaps be a little too long in this case:
menu->bindCallbackEx(std::bind([&](const tgui::Callback& callback, sf::RenderWindow& window) { if (callback.text == "Exit") window.close(); }, std::placeholders::_1, std::ref(window)), tgui::MenuBar::MenuItemClicked);

But I'm afraid that there is no bindCallback function to bind to a specific menu item being clicked. These bindCallback functions are inherited from a base class, and are not specific to the widget.

In the Callback struct, you will have the 'text' member as you can see in the above examples. You can also use the 'index'. This will be 0 for all the menu items in the "File" menu, but if you would also add an "Edit" menu then a callback from there would have index 1.

The callback system is complex, so make sure to read the tutorial and experiment a bit with it.
#1421
Help requests / Re: Troubles with callbacks
28 March 2014, 18:17:19
Neither of the 3 options are correct.
The compiler has to know which function (which is what you pass in your codes), but it also should know on which object it should call this function. So the correct line becomes:
myButton->bindCallbackEx(&MyClass::CallbackFunction, &myClassInstance, tgui::Button::LeftMouseClicked);

Actually that line is just shorthand for the following code:
myButton->bindCallbackEx(std::bind(&MyClass::CallbackFunction, &myClassInstance), tgui::Button::LeftMouseClicked);

When the code is called inside the class fom which you want to call the function, then "&myClassInstance" is just "this".
#1422
Help requests / Re: Troubles with callbacks
28 March 2014, 17:35:58
You can give the buttons an id to identify them.

void callbackFunction(const Callback& callback)
{
   // callback.id will be either 0 or 1 or ... or _worlds.size()-1
}

for(int i=0;i<_worlds.size();i++)
{
    /* ... */
    button->setCallbackId(i);
    button->bindCallbackEx(callbackFunction, tgui::Button::LeftMouseClicked);
    /* ... */
}


The std::bind method is for when you want you callback function to have a parameter other than the Callback struct.

QuoteI don't even know if my way to is good.
It looks good to me.
#1423
I've looked into it, but there doesn't seem to be an easy way to add this.
Loading widgets from a file is still something that is far from being perfect, but I can't immediately do much about it.

I'm afraid you will have to solve it in your c++ code. (GridName, ButtonName1 and ButtonName2 are the names of the widgets in the file)

tgui::Grid::Ptr grid = gui.get("GridName");
grid->addWidget(grid.get("ButtonName1"), 1, 2);
grid->addWidget(grid.get("ButtonName2"), 2, 0);


But of course doing that for all widgets might be a bit long and requires a bit too much hardcoding. So maybe you can do it in another way, using the knowledge that the widgets in the grid are in the same order as they are defined in the file. When you e.g. have a 3x4 grid you can do this:

tgui::Grid::Ptr grid = gui.get("GridName");
auto& widgets = grid.getWidgets();
for (unsigned int row = 0; row < 3; ++row) {
    for (unsigned int col = 0; col < 4; ++col) {
        grid->addWidget(widgets[row*4 + col], row, col);
    }
}


(Codes were written without testing)
#1424
It seems to work fine here.
If you can't solve the problem then you can send me the .cbp file and maybe I can find a mistake in it.
#1425
Thats really strange.

Are you sure that you are using the sfml libraries included in the tgui download?
Are you linking statically or dynamically, in debug or release mode?
You are using MinGW 4.7.1, right?

I'll try it on my windows as well and see if I can reproduce the problem.