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

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.


Messages - theo

Pages: [1] 2
1
Got it working, though my method is a bit hacky.

  • Downloaded the sources of freetype 2.10.4
  • opened the provided visual studio solution (builds\windows\vc2010 (yes this one works on vs2019 too)
  • built it for the desired configuration
  • now VS builds a dll named freetype.dll. I renamed it to freetyped.dll (debug version). Hovering in windows confirms that it is version 2.10.4.
  • copied it to vcpkg\installed\x64-windows\bin (overwrite existing file)
  • now it works. It seems that 2.10.4 and 2.11.0 are binary compatible.

Stackoverflow says that you have to edit header files. This is not necessary anymore. Just choose dll in the solution properties.

Hopefully they fix that bug soon. I do wonder however how they could miss this with any kind of testing on windows (not an entirely insignificant platform).

2
stupid mistake: in vcpkg.json:

"overrides":[{"name":"sfml", "version":"2.10.0"}] -> "overrides":[{"name":"freetype", "version":"2.10.0"}]

But it doesn't make a difference, it still builds freetype 2.11.0

3
Graphics / Re: problem with sf::Text getGlobalBounds() / getLocalBounds()
« on: September 16, 2021, 10:44:42 am »
I see that this is a duplicate for https://en.sfml-dev.org/forums/index.php?topic=28213.0

4
May I ask how you did this? For me it won't work.
I edited the vcpkg.json in the ports\sfml dir to
(click to show/hide)

I got the value of builtin-baseline by doing
git rev-parse HEAD

This didn't do anything for me: it still grabbed freetype version 2.11.0.

Then I edited vcpkg\versions\baseline.json and changed the baseline of freetype to 2.10.0 and I edited the vcpkg.json of freetype to also take 2.10.0:
"version-semver": "2.10.0",

Now it SAYS that it takes 2.10.0. And vcpkg list says 2.10.0 for freetype. But the dll version is STILL 2.11.0 and drawing an sf::Text STILL crashes in freetype.

Maybe the easier way is to compile sfml with cmake and copy the freetype dll into the vcpkg\bin dir

5
Graphics / Re: problem with sf::Text getGlobalBounds() / getLocalBounds()
« on: September 15, 2021, 03:25:42 pm »
interesting detail: the debugger watch suggests that variable t has no vertices

(click to show/hide)

6
Graphics / Re: problem with sf::Text getGlobalBounds() / getLocalBounds()
« on: September 15, 2021, 02:59:58 pm »
The problem seems to be deeper: sf::Text also doesn't draw properly anymore. Very minimal program:

(click to show/hide)

Compiled with visual studio 16.11.3

Installed libraries (via vcpkg):
(click to show/hide)

7
Graphics / problem with sf::Text getGlobalBounds() / getLocalBounds()
« on: September 15, 2021, 02:35:43 pm »
I take the bounds of an sf::Text object:

sf::Text t{};
t.setFont(m_font);  // yes, m_font is loaded and in scope at this point
t.setString("Hello world");
t.setCharacterSize(20);
auto bounds = t.getGlobalBounds();  // same behaviour with getLocalBounds()

This used to work fine, but now I get the following error:

Exception thrown at 0x00007FFCCAAD2B8D (freetyped.dll) in test.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

The only thing that seems to have changed is an upgrade of freetype to version 2.11.0 (through vcpkg). This might be more a bug in freetype than in SFML, but I can't really tell.

8
SFML projects / Re: SFGUI (0.4.0 released)
« on: September 26, 2020, 04:26:57 pm »
I have a problem with Window widgets in SFGUI. What I try to achieve is that if the user right_clicks on an inventory item, a popup appears with a description of the item. I implement this by holding an sfg::Window::Ptr and adding the text to the label in the window. If the window is "opened" (actually happens only the first time), the window is revealed with Show(true). The onCloseButton is bound to a lambda that just hides the window.

The problem is that the window becomes unresponsive in the following scenarios:
- open popup
- drag it around
- "close" the popup (it is actually just hidden). At this point this works.
- "open" it again. Now the correct text appears, but the window will not respond to events anymore. It will not drag or close.

or
- open popup. The correct text appears
- right click on another inventory item. Now the label changes into the expected text, but the window becomes unresponsive.

The label is found with no problem, the text changes as expected. Only the window can not be dragged or hidden anymore. Here the code, it's small enough.

button->GetSignal (sfg::Widget::OnRightClick).Connect ([this, table, index = i * 10 + j] (){show_description (table, index); }); // the inventory is a sfg::Table of sfg::Togglebutton, the index indicates which button is right-clicked

// ...

void Character_sheet::show_description (sfg::Table::Ptr table, size_t index)
{
        // code to determine the description text left out, goes into desc
        auto desc = item_data->description;
        if (index < inv->bag.contents.size ())  // skip if there is no actual item associated with this inventory slot
        {
                if (m_description_popup)
                {
                        m_description_popup->Show (true);
                }
                else
                {
                        m_description_popup = sfg::Window::Create (sfg::Window::Style::TOPLEVEL | sfg::Window::Style::CLOSE);
                        m_description_popup->GetSignal (sfg::Window::OnCloseButton).Connect ([this] (){m_description_popup->Show (false); });
                        auto text = sfg::Label::Create ();
                        text->SetRequisition({ 200.0f,0.0f });
                        text->SetLineWrap (true);
                        text->SetId ("item_description");
                        m_description_popup->Add (text);
                        m_desktop->Add (m_description_popup);
                }
                auto text = find_widget ("item_description");
                text->SetText (desc);
        }
}

template <typename T = sfg::Label>
std::shared_ptr<T> find_widget (const std::string& id)
{
        return std::dynamic_pointer_cast<T>(sfg::Widget::GetWidgetById (id));
}
 

9
I got to the statemanager chapter. A few constructive remarks:

1- You tend to pass very small data-items bij const ref: e.g. void f (const bool&). I don't see what's the merit in that. A bool or an int is probably even smaller than a pointer. Just pass these things by value and use const refs where a copy is (potentially) expensive.
2- You have a tendency of declaring empty destructors. Probably power of habit, but in C++11 this prevents the generation of move constructor and assignment. This will of course not be a problem with classes like eventmanager and statemanager because they will not be moved around anyway, but this is not a good habit.
3- In the draw and update functions of the statemanager, you traverse back and forth to find the last non-transparent state. In the past I used to be a C programmer, so traversing pointer structures is nothing new for me, but the C++ Committee gave us the algorithms library to be used. This code can be rewritten to be a lot more obvious:


#include <algorithm>

using State_elem = std::pair<StateType, BaseState*>>;  // convenience

void StateManager::Draw()
{
  if (m_states.empty() {return;}
  if (m_states.back().second->IsTransparent() && m_states.size() > 1)
  {
    // find last non-transparent state. find_if normally finds the first element that satisfies its predicate,
    // but if we feed it reverse iterators, it searches backwards.
    // I use find_if_not to avoid confusing negative logic.
    auto r_itr = std::find_if_not (m_states.rbegin(), m_states.rend(), [](State_elem e) {return e.second->isTransparent();});
    // we gave find_if_not reverse iterators, it also gives us a reverse iterator. So we have to trick it:
    for (; r_itr != m_states.rbegin(); --r_itr)
    {
      r_itr -> second -> Draw();
    }
  }
  else
  {
    m_states.back().second->Draw();
  }
}



IMHO this code is self-explanatory, except for the little trick with the reverse iterators.

It might be possible to just say

auto r_itr = std::find_if_not (m_states.rbegin(), m_states.rend(), [](auto e) {return e.second -> isTransparent();});


and let the compiler figure out the type of the argument of the predicate.
The algorithm library works brilliantly with lambdas. Every new C++ programmer should learn about that. This also goes for the HasState function: it can be simplified a lot by using find_if. Use find_if to find the state in m_states and use find to find it in m_toRemove. If the state is found in m_states and not found in m_toRemove, the result is true. Otherwise the result is false.


bool StateManager::HasState(const StateType type)  // type is an int, just pass by value
{
  auto state = std::find_if (m_states.begin(), m_states.end(), [type](State_elem e) {return e.first == type;});
  auto remove = std::find(m_toRemove.begin(), m_toRemove.end(), type);
  if (state != m_states.end() && remove == m_toRemove.end())  // found in m_states, not found in m_toRemove
  {
    return true;
  }
  else
  {
    return false;
  }
}


4- The draw and update functions are almost identical. Duplicate code is Not Very Nice. The only differences are the functions calles (IsTransparent vs IsTranscendent, Draw vs Update). It should be possible to make a private helper function that does the searching and that accepts the functions that are used. I haven't worked this out yet. Probably it isn't worth the trouble in this simple case.

10
First of all: I like the book a lot. Thanks for it.

At the moment I'm going through the event manager chapter. I have one question and one remark.

The question:
You store the Binding objects in an unordered_map keyed on name. The only reason for this seems to be to enforce only one Binding per callback, since you never access the bindings map on name. Why is that important? I would drop that restriction, since there are reasons to want multiple bindings to the same callback. For example, if you want to bind <ctrl>-c to some event, you need two bindings: one for left control and one for right control. Differentiating between left and right shift, alt and control seems artificial to me. The user shouldn't be bothered with the technical fact that left and right key have different keycodes. So I would use a std::vector<Binding*> (or better still: std::vector<std::unique_ptr<Binding>> and even silently include double bindings when the user wants ctrl/alt/shift combinations.

The remark:
You do a great job of abstracting the event side of the event manager, but the callbacks are just wrapped function pointers. Why not put a Command pattern on the callback side? See http://gameprogrammingpatterns.com/command.html for a nice explanation. Of course that adds some code and complexity, but it enables some cool features:
1- if the AI also puts Command objects on the queue, enemies (and a demo mode, if applicable) can use the exact same control mechanism as the user-controlled character.
2- you can control all kinds of actors. So the player character is an actor, but the Window class can also be an actor (to handle focus gained/lost, toggle full screen). You could make anything that receives input an actor, using the same mechanism without messy exceptions to the rule.
3- it makes undo easy. In certain situations (think a strategy game where the player has to plan actions for many units before committing the turn) this could be a really nice touch.
Abstracting the callback side as well as the event side makes the event manager even more versatile.

And a minor point: you have many functions return a bool to indicate succes. It seems cleaner and more natural to me to use exceptions for that kind of behaviour. But that could just be me, I do java for a living.

11
SFML projects / Re: SFGUI (0.3.2 released)
« on: July 27, 2017, 03:41:11 pm »
@Parsley:

I don't think that using more than one desktop in SFGUI will work. See the second reply of eXpl0it3r to me:

Quote
As for desktops, not sure if multiple ones make sense.

I guess there are several basic approaches for traversing from one SFGUI screen to the next:

- keep all screens in memory and make sure only one is visible and sensitive at any given time (my approach)
- keep one window and on a navigation event empty it with RemoveAll and fill it again with the widget hierarchy of the next logical screen: you effectively reuse the sfg::Window object.
- on a navigation event destroy the sfg::Window and construct the sfg::Window of the next screen (Landry's approach)

What works best for your situation depends on your project: if the screens are lightweight (no big background graphics etc) and static, my approach works well. If the layout of the screens is dynamic and can be different every time depending on data, or the screens have a big memory footprint,  Landry's approach will work well.

I don't know how expensive destroying and reconstructing sfg::Window objects is. I don't expect that to be a dealbreaker, but if screen transitions become slow, it's probably worth the effort to try reusing it.

Note: I'm not an SFGUI developer, so take my remarks for what they're worth.

12
SFML projects / Re: SFGUI (0.3.2 released)
« on: July 26, 2017, 05:04:36 pm »
@eXpl0it3r

Thanks a lot for your replies, it has been really helpful. I just needed a lightbulb moment and you have provided that.

13
SFML projects / Re: SFGUI (0.3.2 released)
« on: July 26, 2017, 05:03:11 pm »
Hi Landry,

I have solved the problem by keeping all window objects, and just switching the sensitive/visible states. It works perfectly. Making the window insensitive, makes all widgets in the window insensitive, so there is no weird behaviour at all.

I pushed the responsibility of switching state into the manager. So the manager keeps track of the previous window and the next one. Prev is set equal to next at the top of the loop. Next is made active (sensitive and visible). Now the screen is run, the return value is captured in next. Prev is made inactive and the loop repeats. Easy peasy.

The good thing is, that all windows are present in the manager, so switching is really fast. I guess this will turn into a bad thing if there are many windows, or the windows become big in memory footprint. But for a simple wizard, it's perfect. Also, if the user uses the "back" navigation key, he gets the previous screen exactly as he left it. No need to retype text entries, or to reselect many options.

I also base the window layout on configuration in a SQLite database, but that is not  supposed to be dynamic, so not reloading it is not a problem.

14
SFML projects / Re: SFGUI (0.3.2 released)
« on: July 21, 2017, 12:00:33 pm »
Thanks for your responses.

First question: yes, that sounds like a good idea. I got another idea too: split the value of attributes into subvalues: base, bought, bonus. Only "bought" is a spinbutton, the others are regular labels. If the user buys ST, it increases the "bought" subvalue of ST and the "bonus" subvalue of HP. In this system, the values of the interactive widgets don't have to be changed programmatically. And also, the accounting of CP becomes easier. Cost has to be computed only for "bought" attribute points. That makes it both easier for the program to recalculate all values, and for the user to keep track of where his CP budget goes to. It also makes it easier to keep track of free (temporary) bonuses caused by spells, magic items etc. They al go to "bonus" and that way they are not included in calculating the CP cost.

Second question: yes I keep member variables pointing to widgets, so they are easily accessible from the callback functions. Those references will prevent the widgets from being destroyed. That will probably be the reason why they stay visible. This is easily fixed by setting the member variables to nullptr when the widget is no longer needed.

Also for this I have thought up a slightly different approach. The different screen objects stay alive in the screen manager object. I guess it is more efficient to just keep the windows intact, but only make the active screen visible and sensitive. That way it's easy to make a back button that keeps the choices the user made beforehand: just switch the visibility and sensitivity.
So it will work like this:
- the screen manager keeps the SFGUI and desktop objects, they are passed by reference to each screen object in the run () function. Don't want the compiler to copy them. So the run function has three parameters, all references: the SFML rendertarget, sfg::SFGUI and sfg::Desktop.
- each screen has its own sfg::Window object. The GUI layout (the widget hierarchy) is build up in the constructor of the screen object.
- if run () is called by the manager, make the current sfg::Window active: guiwindow -> SetState (sfg::Widget::State::NORMAL); and guiwindow -> Show (true);
- if "next" or "back" button is clicked, just make the current window inactive and invisible: guiwindow -> SetState (sfg::Widget::State::INSENSITIVE); and guiwindow -> Show (false);. Now the manager will call the run () of the appropriate next window. Will making the window INSENSITIVE also make all underlying widgets INSENSITIVE? Otherwise there may remain invisible hot zones on the screen, which is not what I want.
- if the wizard is left altogether, reset all widgets to default value, so the next time the user has a clean start.

Does this approach make sense?

15
SFML projects / Re: SFGUI (0.3.2 released)
« on: July 19, 2017, 01:30:53 pm »
In the meantime I have been doing something else, and run into another problem.

I'm trying to make a wizard-like sequence of GUI screens. You fill in one screen, click "next" and get the next screen. I use the approach described here (https://github.com/SFML/SFML/wiki/Tutorial%3A-Manage-different-Screens) for going from screen to screen.

The problem I observe, is that when I go from screen 1 to screen 2, I see both screens through each other, transparent-like. What I suspect is happening is that both screens have their own sfg::Window object and both are being displayed. The transparancy can be due to the style chosen. My time for this project is little and fragmented (really lost moments), so I have not been able yet to experiment exhaustively.

My question is, what is the best approach for doing what I attempt to do.
- use one sfg::Window and one sfg::Desktop and propagate them through all screens of the wizard. I guess I will have to remove all widgets from the sfg::Window object when going to the next screen. Since RemoveAll doesn't seem to be recursive, this means I will have to keep pointers to all containers, and clean them in the right order.
- at the end of each screen close the sfg::Window and the sfg::Desktop and open new ones in the next screen. Since I still have the SFML RenderTarget, the application window should survive this (does it?). This way, I won't have to traverse the widget hierarchy, but I do get the overhead of opening new sfg::Window and sfg::Desktop objects for each screen.

Another question: is there any hope that the SFGUI website will be back in the forseeable future? Now there is no documentation at all on using themes. On the website there was not much, but at least there was something. Also the forum dedicated to SFGUI was nice and instructive.

I am not an experienced GUI developer. I am a programmer, but normally I do backend stuff. So maybe I miss some insight on how these things are normally done.

Pages: [1] 2