Main Menu

Recent posts

#41
Help requests / Re: Custom childWindow not fu...
Last post by byronhaochen - 26 December 2024, 10:03:37
Thanks! :)
#42
Help requests / Re: Custom childWindow not fu...
Last post by texus - 26 December 2024, 08:38:10
The theme doesn't contain a section for your custom widget, so the BackgroundColor and TitleBarColor in the renderer are never set. No value is apparently transparent here.

In your constructor code you have 'getRendererNoThrow(m_type)', I guess if you change it to 'getRendererNoThrow("ChildWindow")' then it would load correctly.

Alternatively, the Theme class has a few static functions to allow specifying relationships between widgets. I'm guessing you need 'tgui::Theme::addRendererInheritanceParent("YourCustomWidgetName", "ChildWindow");' somewhere before creating the widget to tell the Theme to fall back to the "ChildWindow" section for your custom widget type if no more specific section exists.
#43
Help requests / Custom childWindow not fully ...
Last post by byronhaochen - 26 December 2024, 06:43:17
I use childWindow as the base class to make a custom widget, but the background becomes invisible after drawing. What is the reason for this?  :)
2024-12-26 13-32-29-76.jpg
NewProjectWindow::NewProjectWindow(const char* typeName, bool initRenderer) :
ChildWindow(typeName, false)
{
if (initRenderer)
{
m_renderer = aurora::makeCopied<NewProjectWindowRenderer>();
setRenderer(Theme::getDefault()->getRendererNoThrow(m_type));
}
setTitleButtons(ChildWindow::TitleButton::None);
setTextSize(getGlobalTextSize());

setClientSize({ 450, 350 });
init();
}

#44
Help requests / Re: Combobox with many many it...
Last post by texus - 20 December 2024, 10:57:52
Do you need to assign an id to each item (i.e. second parameter of addItem function)? If not then you can use "addMultipleItems" (added in TGUI 1.6) to add all items at once.

For changing an item, are you using changeItem? That function has to loop through all items to find a matching string, changeItemByIndex is much faster if you know the index of the item that needs to be changed.

I'm not sure if a combo box with so many items is a user-friendly UI design though.
#45
Help requests / Combobox with many many items
Last post by orborneroberts - 20 December 2024, 10:53:14
Hello, I need a combobox with many items, (say over 1000), but if I add all the creation is very slow and even change item is a pain (better in release, but debug it's unusable). It there a workaround for this? Maybe I can load a little number of items (say 20) and when moving the list reload the correct ones. How can I do something like that? Or if are there better solution...
#46
Help requests / Re: Custom canvas keyboard inp...
Last post by InvisibleShoe - 20 December 2024, 05:43:24
Understandable. I've figured out a way to make the GUI and controller work together overnight after looking at how a couple of games manage this.
But it is handy to know how to hook up keyboard input handling to CanvasSFML for other uses :)

Thanks for the help mate
#47
Help requests / Re: Custom canvas keyboard inp...
Last post by texus - 19 December 2024, 16:50:02
The thing to note it that TGUI technically isn't stealing your event. The handleEvent function just returns true, and your code is deciding not to handle the event if that is the case.

It's very difficult for me to decide what handleEvent should return. On one hand, people would only expect it to return true when the key event was actually used, but on the other hand you might not expect it to return false when an edit box is focused and you press backspace while the cursor is at the front or you try to type text in a numeric field.

The return value of handleEvent is something that can help your code decide whether it still needs to process it separately from the gui, but it doesn't has to be the only check. For example you could only execute the "continue;" line if the event wasn't a controller input, or even skip gui.handleEvent altogether for controller inputs.

So you should probably try to first think about when a key event should be handled by your code and when it should be dealt by the GUI. If you can properly define a rule about where the event needs to go to, then it might be more clear for me what you need exactly in case you are stuck implementing it.
#48
Help requests / Re: Custom canvas keyboard inp...
Last post by InvisibleShoe - 19 December 2024, 12:14:17
I just rolled back to an earlier commit where I was rendering to SFML view and the issue appears to be "gui->handleEvent(event)" trying to handle all keyboard events once a widget is clicked.
Mouse events are handled by my controller as they should be.
But clicking on a GUI panel or button will cause the gui to consume all keyboard events until I click on the game area again.

...After some tinkering, it's definitely the "HudRoot" widget stealing focus. I hooked up "gui->unFocusAllWidgets()" to a button and that fixes the issue.

What is best practice for unfocusing widgets to allow other forms of input handling? Is there a way to detect unhandled input events so that unFocusAllWidgets can be called?
#49
Help requests / Re: Custom canvas keyboard inp...
Last post by InvisibleShoe - 19 December 2024, 10:42:45
Excellent. Glad its an easy fix  ;) I'll give it a go.

I did have the game area rendered to a regular SFML view before but I was thinking that my game being fairly GUI heavy and the fact that I want interactive graphs and a minimap rendered to GUI widgets, it would be best to create a custom canvas widget that can gain focus and be interacted with.

While that info does help with creating a custom canvas for graphs and minimaps, I would prefer to have the game area rendering and input handling managed outside of GUI operations.
When I tried this before I had difficulty with TGUI consuming all input events, even when the only thing focused was an empty panel.

In the code below, I previously used insertSpace to create an area for the SFML view to be rendered and everything worked fine, input handling fell through to my controller until I click on any TGUI widget at which point TGUI starts consuming all actions and nothing falls through to my controller anymore.

Do you have any idea how to address this? I would love to go back to using a plain SFML view to render to.

GUI code:

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

auto leftPanel = tgui::VerticalLayout::create();

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

// auto canvas = GameCanvas::create(world);
// 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);

leftPanel->insertSpace(1, 80.0f);

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

auto rightPanel = tgui::VerticalLayout::create();

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

auto button = tgui::Button::create("Steal Focus");
button->onMousePress(
[button](){
    button->setFocused(true);
}
);
topRight->add(button);

button = tgui::Button::create("Quit");
button->onMousePress(
[world](){
    world.add<Tag::ActiveScene, Tag::MenuScene>();
}
);
topRight->add(button);

auto txtArea = tgui::EditBox::create();
txtArea->setPosition(0, 50);
topRight->add(txtArea);

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");

(Previous) Input handling:

sf::Event event;

while(window.window->pollEvent(event)){
    if(event.type == sf::Event::Closed){
         e.world().set( Tag::Status{ Tag::Status::QUIT });
    }
    if(gui.gui->handleEvent(event)){
         continue;
    }
               
    ctrl.ctrl->checkInput(event);
}

Cheers and thanks for the help  :D
#50
Help requests / Re: Custom canvas keyboard inp...
Last post by texus - 19 December 2024, 09:50:34
Key events are only send to the focused widget (and its chain of parents). There were a handful of widgets (like Picture and Canvas) that I considered "unfocusable". Since they never get focused, they never receive the key events. This isn't really documented properly anywhere, I never expected someone to inherit from these classes and turn them into functional widgets instead of just drawings.

You can fix your code by adding the following function to your class:
Code (cpp) Select
bool GameCanvas::canGainFocus() const override
{
    return true;
}

Of course you will only receive the key presses after you clicked the canvas or called canvas->setFocused(true), and you will no longer receive them once the user clicks on a button and the button receives focus. If this isn't what you want, then you should process the key events somewhere else. Either in your event loop, or make a Group/Panel widget that contains all other widgets and already handle key presses in that container.