Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal windows, what am I doing wrong? #897

Open
mietschie opened this issue Jul 15, 2024 · 2 comments
Open

Modal windows, what am I doing wrong? #897

mietschie opened this issue Jul 15, 2024 · 2 comments

Comments

@mietschie
Copy link

Hey,

I'm trying to get modal to work for my project but I can't get it right. Maybe someone can give me a hint why the following minimum example doesn't work? Is it even supposed to work like that? Any help appreciated!

Summary:

  • Main window and modal window are linked via the ftxui::Modal decorator
  • Both windows are decorated with ftxui::CatchEvent decorators
  • On "Return" key the modal window should be shown
  • On "Q" key the modal window should close
#include <ftxui/component/component.hpp>
#include <ftxui/component/event.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/dom/deprecated.hpp>
#include <ftxui/dom/elements.hpp>

int main() {
  auto screen = ftxui::ScreenInteractive::Fullscreen();
  auto showHide = false;

  auto main = ftxui::Renderer([&]() {
    return ftxui::vbox(ftxui::text("main") | ftxui::center) | ftxui::border;
  });
  
  // goal: open modal dialog on Enter key
  main |= ftxui::CatchEvent([&](ftxui::Event event) {
    if (event == ftxui::Event::Return) {
      showHide = true;
      return true;
    }
    return false;
  });

  auto modal = ftxui::Renderer([&]() {
    return ftxui::vbox(ftxui::text("modal") | ftxui::center) | ftxui::border;
  });

  // goal: close modal dialog on Q button
  modal |= ftxui::CatchEvent([&](ftxui::Event event) {
    if (event == ftxui::Event::Character('q')) {
      showHide = false;
      return true;
    }
    return false;
  });

  main |= ftxui::Modal(modal, &showHide);

  screen.Loop(main);
  return 0;
}
@ArthurSonzogni
Copy link
Owner

I believe this is due to both of the component not to be "focusable".
Indeed, the user needs to know "where" the events are applied.
Here, this probably block one this early return.

Ideally, you wouldn't use ftxui::Renderer, this is mostly meant for non interactive component. Nevertheless, it accept a bool focused to allow a minimal kind of interactivity, being 'selected'.

Here is the solution:

#include <ftxui/component/component.hpp>
#include <ftxui/component/event.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/dom/deprecated.hpp>
#include <ftxui/dom/elements.hpp>

int main() {
  auto screen = ftxui::ScreenInteractive::Fullscreen();
  auto showHide = false;

  auto main = ftxui::Renderer([&](bool focused) {
    auto element = ftxui::vbox(ftxui::text("main") | ftxui::center) | ftxui::border;
    if (focused) {
      element |= ftxui::focus;
      element |= ftxui::bold;
    }
    return element;
  });
  
  // goal: open modal dialog on Enter key
  main |= ftxui::CatchEvent([&](ftxui::Event event) {
    if (event == ftxui::Event::Return) {
      showHide = true;
      return true;
    }
    return false;
  });

  auto modal = ftxui::Renderer([&](bool focused) {
    auto element = ftxui::vbox(ftxui::text("modal") | ftxui::center) | ftxui::border;
    if (focused) {
      element |= ftxui::focus;
      element |= ftxui::bold;
    }
    return element;
  });

  // goal: close modal dialog on Q button
  modal |= ftxui::CatchEvent([&](ftxui::Event event) {
    if (event == ftxui::Event::Character('q')) {
      showHide = false;
      return true;
    }
    return false;
  });

  main |= ftxui::Modal(modal, &showHide);

  screen.Loop(main);
  return 0;
}

@mietschie
Copy link
Author

Hey, thank you so much for the quick support. Works like a charm! I'm still learning the possibilities of FTXUI. You're saying you would not use ftxui::Render for this application. What should I use instead, if I - let's say - have a simple vertical container with a bunch of ftxui::MenuEntry's (as main view), which on Enter-key should open a modal dialog showing some detailed data about the entry?

Thanks again, really appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants