Recent Posts

Pages: [1] 2 3 ... 10
1
Help requests / Re: Signals, unbound parameter
« Last post by RitoonL on Yesterday at 17:29:05 »
understood,

Thanks
2
Help requests / Re: Signals, unbound parameter
« Last post by texus on Yesterday at 17:14:00 »
The problem is that _test() is a member function.
Unlike a free function (a function that isn't part of a class), a member function needs to know what object it is called on. If you access member variables or call other member functions then the code needs to know on which object it needs access these members (since you may create multiple Ch_window objects).

Although you don't write any parameters, the c++ compiler will generate a function that is equivalent to the following:
void _test(Ch_window* this);

That is where the "this" object comes from that you can use within a class, behind the scenes it is a parameter passed to all your member functions.
So the function does have a parameter, which is what the connect call is complaining about (it doesn't know what value it has to pass to your this pointer).

Since TGUI needs to know on which object to call the _test function, you have to give it a pointer to the object. Since you are calling the connect function inside a member function of Ch_window and you obviously want to call the _test function on the same object, the pointer to the object is literally your "this" value. You also have to change the function name for it to work properly:
channels->connect("SizeChanged", &Ch_window::_test, this);

Alternatively, you can use a lambda function, which is similar to what TGUI will internally do when you write the above:
channels->connect("SizeChanged", [this]{ _test(); });
3
Help requests / Signals, unbound parameter
« Last post by RitoonL on Yesterday at 16:58:51 »
Hello,

I'm trying to connect the SizeChanged signal from a child window.

I followed the tutorial and tried to do a simple thing to test :


void Ch_window::_test()
{
    cout<<"size changed"<<endl;
}

void Ch_window::channels_window (sf::RenderWindow &window, tgui::Gui& gui)
{
    auto channels = tgui::ChildWindow::create();
    channels->setTitle("Channels");
    channels->setTitleAlignment(tgui::ChildWindow::TitleAlignment::Left);
    channels->setResizable(true);//(tgui::ChildWindow::setResizable=true);
    channels->getRenderer()->setBackgroundColor(sf::Color::Black);
    channels->getRenderer()->setTitleBarHeight(15);
    channels->getRenderer()->setTitleColor(sf::Color::White);
    channels->getRenderer()->setTitleBarColor(sf::Color(20, 30, 60));
    channels->getRenderer()->setBorders(1);
    channels->getRenderer()->setMinimumResizableBorderWidth(3);
    channels->getRenderer()->setBorderColor(sf::Color(20, 30, 60));
    channels->connect("SizeChanged", _test);
}

this give me an error when i run the program

terminate called after throwing an instance of 'tgui::Exception'
  what():  Signal 'SizeChanged' could not provide data for unbound parameters.

i search about thes unbound parameters but did not find much. what i understand is that SizeChanged signal wants to give something to my function but i did not set arguments to my fuction to receive it.

is it newsize ? my _test function should havec a vector2f as argument ? ***edit*** seems not, void _test(sf::Vector2f new_size) did not changed anything.

thanks by advance,

RitoonL

4
Help requests / Re: SFML drawing into a child window
« Last post by RitoonL on Yesterday at 09:49:53 »
Very interesting answer,

i really like the class solution ... Because i can make each window as a class and forget it when it's done or drawing all windows in a class and make them interact easily. Now that you opened my eyes on it, i think making a class for the  windows is a good way. As i want to make magnetic windows, they can pass their coordonates to each other. would be better for windows arrangement.

i'll bookmark this and read it again and again ... I really think passing things in C++ code is the hardest for me, i need more comprehension for this. Hope it will come with experience.

Regards,

RLF
5
Help requests / Re: SFML drawing into a child window
« Last post by texus on 31 May 2020, 23:05:14 »
I see now what the problem was. It's hard to help with how you should pass data to different places because there is a lot of freedom in how to do it exactly without there always being a best way. For the simple case that you have here, returning the value like you are doing is probably the best option, but I'll provide some alternatives that you could keep in mind if you face a similar problem later.

I said earlier that tgui::Canvas::Ptr is a simple pointer and thus copying it isn't a problem. If it would have been a large object then returning it might not have been a good option, passing it by reference would have been better. In some cases you can still return a large object in such a way that it is moved instead of copied, but until you fully understand move semantics it might be a good idea to always assume that a copy would take place and pass large objects by reference parameter.
tgui::Canvas::Ptr canvas;
channels_window(window, gui, canvas);
void channels_window(sf::RenderWindow &window, tgui::Gui& gui, tgui::Canvas::Ptr& canvas)
{
    canvas = tgui::Canvas::create();
    // ...
}
Design wise it might be better to call "tgui::Canvas::create()" before calling the function, but this example is to illustrate that you can pass an uninitialized object into the function which will initialize it.

Another alternative is to use a class member. It channel_sorting and channels_window wouldn't be free functions but instead were part of the same class then you could simply give that class a tgui::Canvas::Ptr member that you initialize in channels_window and use in channel_sorting. There is no need for passing parameters and return values in such case.

Yet another alternative would be to store the tgui::Canvas::Ptr inside the Channel class itself. This might not be a very good option here because you could have many channels and you would unnecessarily be making each channel class a few bytes larger, but it would also be an option in which you wouldn't need to pass the canvas in channel_sorting and draw_channel.

If you e.g. need sf::RenderWindow, tgui::Gui and tgui::Canvas::Ptr in a lot of places then another option would even become to put those together into a class and pass an object of that class around by reference instead of passing them separately.

An alternative that is specific to TGUI widgets is letting the gui store the widget. You can pass a unique name as parameter to the add function that allows you to retrieve it later:
gui.add(canvas, "MyCanvas");
tgui::Widget::Ptr widget = gui.get("MyCanvas"); // Get the widget back, but as a base class on which you can't call Canvas-specific function
tgui::Canvas::Ptr canvas = gui.get<tgui::Canvas>("MyCanvas"); // Get the widget back, casted to the right type (might crash if widget with name "MyCanvas" wasn't a tgui::Canvas)
So as long as you have access to the tgui::Gui object, you can get access to any widget that was added to it.

So as you can see there are tons of options to get the canvas in the right place (even more than the ones I wrote), but knowing which design fits your needs best comes with experience by just trying and learning which choices didn't work well. If you are unsure which design is better, the best design is most often the one that requires you to write as little code as possible  (while makes the code as readable and understandable as possible, i.e. not focusing on the line count).


Not really related, but I wouldn't use the "ch(x)" define. It makes the code harder to read. If you really need to shorten the line (e.g. if you need to write several lines containing "tab_Channel[address_channel[x]]") then it would be better to just make a reference to the object:
auto& ch = tab_Channel[address_channel[x]];
ch->draw_channel(canvas,column*52,row*72);
6
Help requests / Re: SFML drawing into a child window
« Last post by RitoonL on 31 May 2020, 17:00:52 »
Hello Texus

Coding is definitly a interesting puzzle.

tgui::Canvas::Ptr canvas = channels_window(window, gui); // that was the solution

i found the solution myself, i was too focused of what the fuctions were taking and never worried of what they were returning. I needed the first fuction called in the main returning a pointer of the canvas, so i could call my second function inside the loop, passing the canva. The canva is now refreshed. Everything is not perfect yet, but still, i'm progressing !!!

thanks for all the time you spent helping me, i know it's no fun helping newbies, specially when they lack of basic knowledges like me, you're not intended to be my teatcher but you had the patience to :) i'm grateful for this.

Regards,

RitoonL
7
Help requests / Re: SFML drawing into a child window
« Last post by texus on 30 May 2020, 20:09:47 »
I don't have much time now, so maybe if I have more time to read your post I will understand it better, but right now I'm not sure where your problem is exactly. So I'll just quickly comment on some of the things you said.

Quote
I know that i must use canva->display() in my main or in a fuction called in the main, but i don't know how to do as the compiler wants the canvas to be declared
What exactly is the error? Is there no canvas variable (because no such object is declared there), or doesn't it know tgui::Canvas (because you wouldn't be including TGUI.hpp)?

Quote
but if i use (tgui::Canvas::Ptr &canvas) as argument of the fuction, wich prevent copying the canvas, i can't use the function in the main
Then there is something wrong about the way you call it in your main function. You need to have a reference to an existing object, it won't work if you e.g. try to create a new canvas on the same line as your function call.
That being said, TGUI widgets are wrapped in pointers. Without the "&" you are only copying the pointer, which still points to the same canvas, the canvas never gets copied. Taking the argument by reference would only be marginally faster because the Ptr is a std::shared_ptr which has to count the amount of pointers to the object: if it is copied then it has to increment the counter, if you take it by reference then it doesn't. So don't worry about passing it by value, but if the code doesn't compile when you try to use a reference then there is something wrong.

Quote
Edit : I tried to declare
tgui::Canvas::Ptr canvas;
This is equivalent of code like this:
int *p;
In the best case p would be a nullptr, in the worst case it points to a random memory address. This is why it crashes if you try to use it, you need to actually create the canvas (so that the pointer points to something):
tgui::Canvas::Ptr canvas = tgui::Canvas::create();

It might help if you created a small demo application that would show the issue (just a main function with just a few functions next to it that would actually be runnable on my pc). Only being able to see some of the code means that I would have to make assumptions about how the rest looks. I know for example that you did something wrong in main, but I can't know what. So it's a bit disorienting to follow what is going on, and right now I don't have time to really try and figure it out.
8
Help requests / Re: SFML drawing into a child window
« Last post by RitoonL on 30 May 2020, 19:00:30 »
the features you just add seems very interesting, we'll look at it...

I tought i finished with this canvas code, but i'm struggling again with one thing.

I guess i'm not structuring my code correctly.

void channel_sorting(tgui::Canvas::Ptr &canvas)  // the fuction can't be called in the main because it's waiting &canvas as argument
{
    int displayed_channels=0;
    for(uint16_t i=0;i<1025;i++)
        {
            uint16_t column = (displayed_channels%10 );
            uint16_t row = (displayed_channels/10);
        if(address_channel[i]>0)
        {
            ch(i) draw_channel(canvas,column*52,row*72);//ch(i) is #define ch(x) tab_Channel[address_channel[x]]->
            displayed_channels++;
        }
     canvas->display();
    }
}


void channels_window(sf::RenderWindow &window, tgui::Gui& gui)
{
    auto channels = tgui::ChildWindow::create();
    channels->setTitle("Channels");
    channels->setTitleAlignment(tgui::ChildWindow::TitleAlignment::Left);
    channels->setResizable(true);//(tgui::ChildWindow::setResizable=true);
    channels->getRenderer()->setBackgroundColor(sf::Color::Black);
    channels->getRenderer()->setTitleBarHeight(15);
    channels->getRenderer()->setTitleColor(sf::Color::White);
    channels->getRenderer()->setTitleBarColor(sf::Color(20, 30, 60));
    channels->getRenderer()->setBorders(1);
    channels->getRenderer()->setMinimumResizableBorderWidth(3);
    channels->getRenderer()->setBorderColor(sf::Color(20, 30, 60));

    auto scrollbar = tgui::Scrollbar::create();
    scrollbar->getRenderer()->setTrackColor(sf::Color(20, 30, 60));
    scrollbar->getRenderer()->setThumbColor(sf::Color(70, 70, 70));
    scrollbar->getRenderer()->setThumbColorHover(sf::Color(70, 70, 70));
    scrollbar->getRenderer()->setArrowBackgroundColor(sf::Color(20, 30, 60));
    scrollbar->getRenderer()->setArrowBackgroundColorHover(sf::Color(20, 30, 60));
    scrollbar->getRenderer()->setArrowColor(sf::Color(70, 70, 70));
    scrollbar->getRenderer()->setArrowColorHover (sf::Color(70, 70, 70));
    scrollbar->setSize({10, bindHeight(channels)});
    scrollbar->setPosition({"100% - width", 0});

    auto channel_canvas= tgui::Canvas::create();
    channel_canvas->setSize(350,1000);

    sf::VertexArray channel_quad;

    gui.add(channels);
    channels->add(scrollbar);
    channels->add(channel_canvas);
    channel_sorting(channel_canvas);
}

in void channel_sorting

i'm creating the objects and formatting them. if i create 20 channels objects, they will be displayed in 2 colums of 10. columns and rows will adapt the size of the window in the future.

in void channels_window

i'm creating the channel window, 1 child window, 1 scroll bar and 1 canva (channel_canva), i will do an adaptative code later for the size of the canva, depending on how many channels are displayed, the scrollbar will be in relation of the canva to scroll channels out of the child window, but tis is not the problem i have now.

when the program starts, channels objects are not created. They are created by the user and the user can create more at anytime, it also have dynamic texts and colors. This part of the program works great.

the main problem is that i can't figure how to update the canva. i tried many solutions but the only way i found to update the canva is calling void channel_window() in the main loop wich duplicates all the GUI object each time the loop executes, but i can see my channels well sorted in the canvas, wich prove that i draw on it.

i copied the canva to channel_canva, i'm not proud of that, but if i use (tgui::Canvas::Ptr &canvas) as argument of the fuction, wich prevent copying the canvas, i can't use the function in the main.

I know that i must use canva->display() in my main or in a fuction called in the main, but i don't know how to do as the compiler wants the canvas to be declared . I think i'm lacking of knowledge in C++ to do what i want, but as you know me now, i'm fast learner if someone can put me on good rails.

Edit : I tried to declare
tgui::Canvas::Ptr canvas;
in the main and passig it to the functions, it compiles with no error but crashes when i execute the program.

thanks by advance
RitoonL
9
Help requests / Re: SFML drawing into a child window
« Last post by texus on 29 May 2020, 19:45:21 »
Quote
we're really seeking every opportunity to refresh only what we need
we're trying to keep in mind every opportunity to optimize display
By coincidence I actually fixed an issue today related to this ability. If you were to only draw the screen after you received an event (to minimize the amount of times you need to redraw the screen) then the cursor in edit box would for example stop to blink. Since there was no way to know when the cursor appears and disappears, you would still need to regularly draw the gui even when not receiving events (and you would waste CPU usage as most of the frames nothing would change).

In the 0.8 branch on github, I just made a change that allows you to know when a widget requires the screen to be refreshed (the change was already made in 0.9-dev last week, but I just backported it now). You would need to first call the following to decouple updating time and drawing in TGUI:
gui.setDrawingUpdatesTime(false);

Then every frame, update the time:
bool screenNeedsUpdate = gui.updateTime();

The screenNeedsUpdate variable will become true when something changes in the gui. It almost always will return false, but when an edit box or text box is focused it will return true twice per second so that you can update the screen to show the blinking cursor without having to refresh the screen more than you have to. If you use the showWithEffect or hideWithEffect functions in widget then the update function will return true the whole time while the animation plays, so you would still want to limit the amount of frames being rendered some other way if you want to use those functions.
10
Help requests / Re: SFML drawing into a child window
« Last post by RitoonL on 29 May 2020, 12:52:18 »
Hello Texus,

Thanx for your answer, it's usefull again.

You really told me exactly what i was seeking without haveing to ask. Passing the already drawn entitys ... i'll do that.

I have to write the refreshing routine of the canva, i will maybe have questions about that later, but for now, i'm happy, i can pass what i need.

We're trying to optimize display as much as we can, so we're really seeking every opportunity to refresh only what we need and not everything every frame, because we want the software to run on Raspberry pi also. We compiled on a Raspi 3 today with success ... it could not run on a Raspi 2. It's still a previous version of the work that is not using tgui yet, but we're trying to keep in mind every opportunity to optimize display.

Well, i must thank you really much for your work and for your precious help also, be sure that i will ask more in the future !

Regards,

RitoonL



Pages: [1] 2 3 ... 10