ArthurSonzogni / FTXUI

:computer: C++ Functional Terminal User Interface. :heart:
MIT License
6.9k stars 415 forks source link

window element with light border style #899

Open MarcelFerrari opened 3 months ago

MarcelFerrari commented 3 months ago

Hi all,

I am trying to create a window element with a light border style similarly to what is specified here.

Example:

// With specifying border
Element document = window(text("Title"),
                          text("content"),
                          ROUNDED
                   );

My code looks like this:

// FTXUI includes
#include <ftxui/component/captured_mouse.hpp>
#include <ftxui/component/component.hpp>
#include <ftxui/component/component_base.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/dom/elements.hpp>

using namespace ftxui;

int main()
{
    auto frame = Renderer([] {
        return window(text("Example UI"), text("Hello, World!"), LIGHT);
    });

    screen.Loop(frame);
    return 0;
}

But it fails to compile with the following error:

/home/mferrari/nvimon/tests/test_ui.cpp: In lambda function:
/home/mferrari/nvimon/tests/test_ui.cpp:51:22: error: too many arguments to function ‘ftxui::Element ftxui::window(Element, Element)’
   51 |         return window(text("Example UI"), text("Hello, World!"), LIGHT);
      |                ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/mferrari/FTXUI-5.0.0/build/install/include/ftxui/component/component_base.hpp:11,
                 from /home/mferrari/FTXUI-5.0.0/build/install/include/ftxui/component/component.hpp:13,
                 from /home/mferrari/nvimon/tests/test_ui.cpp:3:
/home/mferrari/FTXUI-5.0.0/build/install/include/ftxui/dom/elements.hpp:83:9: note: declared here
   83 | Element window(Element title, Element content);
      |         ^~~~~~
/home/mferrari/nvimon/tests/test_ui.cpp: In function ‘int main()’:
/home/mferrari/nvimon/tests/test_ui.cpp:54:5: error: ‘screen’ was not declared in this scope
   54 |     screen.Loop(frame);
      |     ^~~~~~
make[2]: *** [CMakeFiles/test_ui.dir/build.make:76: CMakeFiles/test_ui.dir/tests/test_ui.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:240: CMakeFiles/test_ui.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

It seems like there is no definition for window(Element, Element, BorderStyle) after all.

This is confirmed when looking into ftxui/dom/elements.hpp:

[mferrari@sbrinz1]~/nvimon/build% cat /home/mferrari/FTXUI-5.0.0/build/install/include/ftxui/dom/elements.hpp | 
grep -i window
Element window(Element title, Element content);

Although if wee look at border.cpp we do find the function:

 /// @brief Draw window with a title and a border around the element.
 /// @param title The title of the window.
 /// @param content The element to be wrapped.
 /// @param border The style of the border. Default is ROUNDED.
 /// @ingroup dom
 /// @see border
 ///
 /// ### Example
 ///
 /// ```cpp
 /// Element document = window(text("Title"),
 ///                           text("content")
 ///                    );
 ///
 /// // With specifying border
 /// Element document = window(text("Title"),
 ///                           text("content"),
 ///                           ROUNDED
 ///                    );
 /// ```
 ///
 /// ### Output
 ///
 /// ```bash
 /// ┌Title──┐
 /// │content│
 /// └───────┘
 /// ```
 Element window(Element title, Element content, BorderStyle border) {
   return std::make_shared<Border>(unpack(std::move(content), std::move(title)),
                                   border);
 }

Is it just missing from elements.hpp? What is the recommended way to create windows with different border styles without modifying the FTXUI source code or including extra files for this?

Many thanks in advance,

Marcel

dty2 commented 3 months ago

Hi, If you want to use loop function for Component, you can try this

...
    auto screen = ScreenInteractive::FitComponent();
    auto frame = Renderer([=](bool focused){
        return window(text("Example UI"), text("Hello, World!"), LIGHT);
    });
    screen.Loop(frame);
...

If you just want to show a element, you can try this

...
  auto document = window(text("Example UI"), text("Hello, World!"), LIGHT);
  auto screen = Screen::Create(
      Dimension::Full(),
      Dimension::Fit(document);
  );
  screen.Print();
...

hope this can help you . And I advise you to check examples. There are many method of application of dom or component

dty2 commented 3 months ago

Oh, If you want to use Component "Window", not dom "window" you can check example "https://github.com/ArthurSonzogni/FTXUI/blob/main/examples/component/window.cpp"

finally... if you want to use Renderer() there are two kinds of override function first is like Renderer([=](bool focused){ return text("ok"); }); second is like

auto example = Button("ok", []{});
Renderer(example, [=]{ return example->Render() | color(Color::Black); });