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

Topics - InvisibleShoe

#1
Help requests / Custom canvas keyboard input
19 December 2024, 06:02:32
Hi again,
I'm trying to hookup a controller to a custom CanvasSFML widget and can't get key events to register. Mouse move and click work fine.

Header:
class GameCanvas : public tgui::CanvasSFML{
public:
    using Ptr = std::shared_ptr<GameCanvas>;

    GameCanvas(flecs::world& w);
    static GameCanvas::Ptr create(flecs::world& w);

    bool canHandleKeyPress(const tgui::Event::KeyEvent& event) override;
    void keyPressed (const tgui::Event::KeyEvent& event) override;
    bool leftMousePressed(tgui::Vector2f pos) override;
    void leftMouseReleased(tgui::Vector2f pos) override;
    void rightMousePressed(tgui::Vector2f pos) override;
    void rightMouseReleased(tgui::Vector2f pos) override;
    void mouseMoved(tgui::Vector2f pos) override;

    bool isFocused() const{
        bool f = tgui::CanvasSFML::isFocused();
        std::cout << "GameCanvas::isFocused(): " << (f ? "True" : "False") << std::endl;

        return f;
    }

    tgui::SignalTyped<tgui::Event::KeyEvent> onKeyPress = {"onKeyPress"};
protected:
    tgui::Signal& getSignal(tgui::String signalName) override;
private:
    flecs::world world;
};

src:
#include "gameCanvas.hpp"

GameCanvas::GameCanvas(flecs::world& w) : tgui::CanvasSFML(), world(w) {
    onKeyPress(
        [this](const tgui::Event::KeyEvent& event){
            Tag::InputCtrl* ctrl = world.lookup("Tag::GameScene").get_mut<Tag::InputCtrl>();
            ctrl->ctrl->onKeyEvent(event);
        }
    );
}

GameCanvas::Ptr GameCanvas::create(flecs::world& w){
    auto canvas = std::make_shared<GameCanvas>(w);
    return canvas;
}

void GameCanvas::keyPressed (const tgui::Event::KeyEvent& event){
    std::cout << "GameCanvas::keyPressed()" << std::endl;
    tgui::CanvasSFML::keyPressed(event);

    onKeyPress.emit(this, event);
}
bool GameCanvas::leftMousePressed(tgui::Vector2f pos){
    tgui::CanvasSFML::leftMousePressed(pos);

    return false;
}
void GameCanvas::leftMouseReleased(tgui::Vector2f pos){
    tgui::CanvasSFML::leftMouseReleased(pos);

    std::cout << "GameCanvas::leftMouseReleased()" << std::endl;
}
void GameCanvas::rightMousePressed(tgui::Vector2f pos){
    tgui::CanvasSFML::rightMousePressed(pos);
}
void GameCanvas::rightMouseReleased(tgui::Vector2f pos){
    tgui::CanvasSFML::rightMouseReleased(pos);
}
void GameCanvas::mouseMoved(tgui::Vector2f pos){
    tgui::CanvasSFML::mouseMoved(pos);

    Tag::InputCtrl* ctrl = world.lookup("Tag::GameScene").get_mut<Tag::InputCtrl>();
    ctrl->ctrl->onMouseMoveEvent(pos - getPosition());
}

bool GameCanvas::canHandleKeyPress(const tgui::Event::KeyEvent& event){
    std::cout << "GameCanvas::canHandleKeyPress()" << std::endl;

    return true;
}

tgui::Signal& GameCanvas::getSignal(tgui::String signalName) {
    std::cout << "GameCanvas::getSignal()" << std::endl;

    if (signalName == onKeyPress.getName())
        return onKeyPress;
    else
        return tgui::CanvasSFML::getSignal(std::move(signalName));
}


The log messages from isFocused, keyPressed, canHandleKeyPress and getSignal never get called but the messages/actions in mouseMoved and leftMouseReleased do.

The canvas hierarchy is: GameCanvas > VerticalLayout["LeftPanel"] > HorizontalLayout["HudRoot"] > RootContainer.



I've looked through the forums, the tutorial pages on signals and custom widgets, and TGUI source code, especially EditBox, but I just can't seem to figure out how to get the canvas to receive keyboard input.

If someone could point out what I'm doing wrong in the above code or provide me some basic code showing how to create a custom canvas with keyPress functionality, I'd greatly appreciate it.
Cheers 
#2
Help requests / CanvasSFML rendering frozen
16 December 2024, 10:07:17
Hi
I have my game screen setup as below:

    auto gui = world.get_mut<Tag::GuiRoot>();
    auto hudRoot = tgui::HorizontalLayout::create();

// LEFT WIDGETS

    auto leftPanel = tgui::VerticalLayout::create();
    leftPanel->setFocusable(false);

    auto topLeft = tgui::Panel::create();
    topLeft->getRenderer()->setBackgroundColor(sf::Color::Green);
    leftPanel->add(topLeft);

    auto canvas = tgui::CanvasSFML::create();
    leftPanel->add(canvas, "GameCanvas");
    world.set( Tag::GameCanvas{canvas} );

    leftPanel->setRatio(canvas, 15.0f);

    auto bottomLeft = tgui::Panel::create();
    bottomLeft->getRenderer()->setBackgroundColor(sf::Color::Blue);
    leftPanel->add(bottomLeft);

    hudRoot->add(leftPanel, "LeftPanel");

// RIGHT WIDGETS
    auto rightPanel = tgui::VerticalLayout::create();
    // rightPanel->setFocusable(false);

    auto topRight = tgui::Panel::create();
    topRight->getRenderer()->setBackgroundColor(sf::Color::Green);
    rightPanel->add(topRight);

    auto bottomRight = tgui::Panel::create();
    bottomRight->getRenderer()->setBackgroundColor(sf::Color::Blue);
    rightPanel->add(bottomRight);

    hudRoot->add(rightPanel, "RightPanel");
    hudRoot->setRatio(rightPanel, 0.3f);

    hudRoot->setVisible(false);

    gui->gui->add(hudRoot, "HudRoot");

The render process looks similar to:

canvas->clear(sf::Color::Black);
window->clear(sf::Color::White);

// render sprites to canvas

canvas->display();

gui->draw();

window->display()


Canvas rendering works fine on startup but as soon as I click on a gui widget(eg the right panel above) the canvas stops redrawing and won't unfreeze.
If I disable focus on the widget then the canvas stops freezing, so it seems to be an issue with widgets stealing focus from the canvas.
I've run my code in debug with breakpoints and the sprite rendering system is running in the background but the window stops responding to input and the canvas rendering stops.

Can anyone help with this? I was hoping to embed canvas widgets in a few places in a similar manner.

Cheers