component(组件模块)

component(组件模块)

title-img

ftxui::component 模块定义了产生交互式组件的逻辑,这些组件能够响应用户事件(键盘、鼠标等)。

examples 章节提供了一系列示例。

ftxui::ScreenInteractive 定义了渲染组件的主循环。

ftxui::Component 是指向 ftxui::ComponentBase 的共享指针。后者定义了:

  • ftxui::ComponentBase::Render():如何渲染界面。
  • ftxui::ComponentBase::OnEvent():如何响应事件。
  • ftxui::ComponentBase::Add():在两个组件之间构建父子关系。组件树用于定义如何使用键盘进行导航。

ftxui::Element 用于渲染单个帧。

ftxui::Component 用于渲染动态用户界面,生成多个帧,并在事件发生时更新其状态。

多个组件的图库。(演示

image

所有预定义的组件可在 “ftxui/dom/component.hpp” 中找到。

\include ftxui/component/component.hpp

输入框(component::input)

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Input() 生成。

@htmlonly

@endhtmlonly

过滤输入

可以使用 ftxui::CatchEvent 过滤输入组件接收的字符。

std::string phone_number;
Component input = Input(&phone_number, "电话号码");

// 过滤非数字字符。
input |= CatchEvent([&](Event event) {
  return event.is_character() && !std::isdigit(event.character()[0]);
});

// 过滤超过10个字符后的输入。
input |= CatchEvent([&](Event event) {
  return event.is_character() && phone_number.size() >= 10;
});

菜单 (component-menu)

定义一个菜单对象。它包含一个条目列表,其中一项被选中。

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Menu() 生成。

@htmlonly

@endhtmlonly

切换按钮

一种特殊类型的菜单。条目水平显示。

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Toggle() 生成。

@htmlonly

@endhtmlonly

复选框

此组件定义一个复选框。它是一个可以打开/关闭的单个条目。

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Checkbox() 生成。

@htmlonly

@endhtmlonly

单选按钮

单选框组件。这是一个条目列表,其中一项可以被选中。

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Radiobox() 生成。

@htmlonly

@endhtmlonly

下拉菜单

下拉菜单是一个组件,打开时显示一个元素列表供用户选择。

示例

youtube-video-gif (3)

由 “ftxui/component/component.hpp” 中的 ftxui::Dropdown() 生成。

滑块

表示一个滑块对象,它由一个带有分箱中间间隔的范围组成。可以通过 ftxui::Slider() 创建。

示例

image

由 “ftxui/component/component.hpp” 中的 ftxui::Slider() 生成。

渲染器

由 \ref ftxui/component/component.hpp 中的 ftxui::Renderer() 生成。此组件通过使用不同的函数来渲染界面,从而装饰另一个组件。

示例:

auto inner = [...]

auto renderer = Renderer(inner, [&] {
  return inner->Render() | border
});

ftxui::Renderer 也支持组件装饰器模式:

auto component = [...]
component = component
  | Renderer([](Element e) { return e | border))
  | Renderer(bold)

作为简写形式,您还可以将组件与元素装饰器组合:

auto component = [...]
component = component | border | bold;

事件捕获

由 \ref ftxui/component/component.hpp 中的 ftxui::CatchEvent() 生成。此组件装饰其他组件,在底层组件之前捕获事件。

示例:

auto screen = ScreenInteractive::TerminalOutput();
auto renderer = Renderer([] {
  return text("我的界面");
});
auto component = CatchEvent(renderer, [&](Event event) {
  if (event == Event::Character('q')) {
    screen.ExitLoopClosure()();
    return true;
  }
  return false;
});
screen.Loop(component);

ftxui::CatchEvent 也可以用作装饰器:

component = component
  | CatchEvent(handler_1)
  | CatchEvent(handler_2)
  | CatchEvent(handler_3)
  ;

可折叠组件

对于用户可切换显示/隐藏的视觉元素非常有用。本质上是 ftxui::Checkbox()ftxui::Maybe() 组件的组合。

auto collapsible = Collapsible("显示更多", inner_element);

条件显示组件

由 \ref ftxui/component/component.hpp 中的 ftxui::Maybe() 生成。此组件可用于通过布尔值或谓词显示/隐藏任何其他组件。

使用布尔值的示例:

bool show = true;
auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, &show)

使用谓词的示例:

auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, [&] { return time > 10; })

通常,ftxui::Maybe 也可以用作装饰器:

component = component
  | Maybe(&a_boolean)
  | Maybe([&] { return time > 10; })
  ;

容器

水平容器

由 “ftxui/component/component.hpp” 中的 ftxui::Container::Horizontal() 生成。它水平显示组件列表并处理键盘/鼠标导航。

垂直容器

由 “ftxui/component/component.hpp” 中的 ftxui::Container::Vertical() 生成。它垂直显示组件列表并处理键盘/鼠标导航。

标签页容器

由 “ftxui/component/component.hpp” 中的 ftxui::Container::Tab() 生成。它接收一个组件列表并只显示其中一个。这对于实现标签栏非常有用。

垂直

ezgif com-gif-maker (1)

水平

ezgif com-gif-maker (2)

可调整分割

定义两个子组件之间的水平或垂直分隔。分隔线的位置可通过鼠标调整和控制。有四种可能的分隔方式:

  • ftxui::ResizableSplitLeft()
  • ftxui::ResizableSplitRight()
  • ftxui::ResizableSplitTop()
  • ftxui::ResizableSplitBottom() 来自 “ftxui/component/component.hpp”

示例

ezgif com-gif-maker

@htmlonly

@endhtmlonly

强制帧重绘

通常,ftxui::ScreenInteractive::Loop() 负责在处理完新的事件组(例如键盘、鼠标、窗口调整大小等)后绘制新帧。但是,您可能希望响应FTXUI未知的任意事件。为此,您必须通过线程使用 ftxui::ScreenInteractive::PostEvent这是线程安全的)发布事件。您需要发布 ftxui::Event::Custom 事件。

示例:

screen->PostEvent(Event::Custom);

如果不需要处理新事件,可以使用:

screen->RequestAnimationFrame();