container.cpp
algorithm
cstddef
memory
utility
ftxui/component/component.hpp
ftxui/component/component_base.hpp
ftxui/component/event.hpp
ftxui/component/mouse.hpp
ftxui/dom/elements.hpp
ftxui/screen/box.hpp
ftxui/component/animation.hpp
ftxui/component/captured_mouse.hpp
ftxui/component/component.hpp
ftxui/component/component_base.hpp
ftxui/component/component_options.hpp
ftxui/component/event.hpp
ftxui/component/mouse.hpp
ftxui/dom/canvas.hpp
ftxui/dom/deprecated.hpp
ftxui/dom/direction.hpp
ftxui/dom/elements.hpp
ftxui/dom/flexbox_config.hpp
ftxui/dom/linear_gradient.hpp
ftxui/dom/node.hpp
ftxui/dom/requirement.hpp
ftxui/dom/selection.hpp
ftxui/screen/box.hpp
ftxui/screen/color.hpp
ftxui/screen/image.hpp
ftxui/screen/pixel.hpp
ftxui/screen/screen.hpp
ftxui/screen/string.hpp
ftxui/screen/terminal.hpp
ftxui/util/autoreset.hpp
ftxui/util/ref.hpp
src/ftxui/component/container.cpp
algorithm
chrono
cstddef
cstdint
ftxui/dom/take_any_args.hpp
functional
memory
optional
sstream
string
unordered_map
utility
variant
vector
ftxui::ContainerBase
ftxui::VerticalContainer
ftxui::HorizontalContainer
ftxui::TabContainer
ftxui::StackedContainer
ftxui
ftxui::Container

    //Copyright2020ArthurSonzogni.Allrightsreserved.
    //UseofthissourcecodeisgovernedbytheMITlicensethatcanbefoundin
    //theLICENSEfile.
    #include<algorithm>//formax,min
    #include<cstddef>//forsize_t
    #include<memory>//formake_shared,__shared_ptr_access,allocator,shared_ptr,allocator_traits<>::value_type
    #include<utility>//formove

    #include"ftxui/component/component.hpp"//forHorizontal,Vertical,Tab
    #include"ftxui/component/component_base.hpp"//forComponents,Component,ComponentBase
    #include"ftxui/component/event.hpp"//forEvent,Event::Tab,Event::TabReverse,Event::ArrowDown,Event::ArrowLeft,Event::ArrowRight,Event::ArrowUp,Event::End,Event::Home,Event::PageDown,Event::PageUp
    #include"ftxui/component/mouse.hpp"//forMouse,Mouse::WheelDown,Mouse::WheelUp
    #include"ftxui/dom/elements.hpp"//fortext,Elements,operator|,reflect,Element,hbox,vbox
    #include"ftxui/screen/box.hpp"//forBox

    namespaceftxui{

    classContainerBase:publicComponentBase{
    public:
    ContainerBase(Componentschildren,int*selector)
    :selector_(selector?selector:&selected_){
    for(Component&child:children){
    Add(std::move(child));
    }
    }

    //Componentoverride.
    boolOnEvent(Eventevent)override{
    if(event.is_mouse()){
    returnOnMouseEvent(event);
    }

    if(!Focused()){
    returnfalse;
    }

    if(ActiveChild()&&ActiveChild()->OnEvent(event)){
    returntrue;
    }

    returnEventHandler(event);
    }

    ComponentActiveChild()override{
    if(children_.empty()){
    returnnullptr;
    }

    returnchildren_[static_cast<size_t>(*selector_)%children_.size()];
    }

    voidSetActiveChild(ComponentBase*child)override{
    for(size_ti=0;i<children_.size();++i){
    if(children_[i].get()==child){
    *selector_=static_cast<int>(i);
    return;
    }
    }
    }

    protected:
    //Handlers
    virtualboolEventHandler(Event/*unused*/){returnfalse;}//NOLINT

    virtualboolOnMouseEvent(Eventevent){
    returnComponentBase::OnEvent(std::move(event));
    }

    intselected_=0;
    int*selector_=nullptr;

    voidMoveSelector(intdir){
    for(inti=*selector_+dir;i>=0&&i<int(children_.size());
    i+=dir){
    if(children_[i]->Focusable()){
    *selector_=i;
    return;
    }
    }
    }

    voidMoveSelectorWrap(intdir){
    if(children_.empty()){
    return;
    }
    for(size_toffset=1;offset<children_.size();++offset){
    constsize_ti=
    (*selector_+offset*dir+children_.size())%children_.size();
    if(children_[i]->Focusable()){
    *selector_=int(i);
    return;
    }
    }
    }
    };

    classVerticalContainer:publicContainerBase{
    public:
    usingContainerBase::ContainerBase;

    ElementOnRender()override{
    Elementselements;
    elements.reserve(children_.size());
    for(auto&it:children_){
    elements.push_back(it->Render());
    }
    if(elements.empty()){
    returntext("Emptycontainer")|reflect(box_);
    }
    returnvbox(std::move(elements))|reflect(box_);
    }

    boolEventHandler(Eventevent)override{
    constintold_selected=*selector_;
    if(event==Event::ArrowUp||event==Event::Character('k')){
    MoveSelector(-1);
    }
    if(event==Event::ArrowDown||event==Event::Character('j')){
    MoveSelector(+1);
    }
    if(event==Event::PageUp){
    for(inti=0;i<box_.y_max-box_.y_min;++i){
    MoveSelector(-1);
    }
    }
    if(event==Event::PageDown){
    for(inti=0;i<box_.y_max-box_.y_min;++i){
    MoveSelector(1);
    }
    }
    if(event==Event::Home){
    for(size_ti=0;i<children_.size();++i){
    MoveSelector(-1);
    }
    }
    if(event==Event::End){
    for(size_ti=0;i<children_.size();++i){
    MoveSelector(1);
    }
    }
    if(event==Event::Tab){
    MoveSelectorWrap(+1);
    }
    if(event==Event::TabReverse){
    MoveSelectorWrap(-1);
    }

    *selector_=std::max(0,std::min(int(children_.size())-1,*selector_));
    returnold_selected!=*selector_;
    }

    boolOnMouseEvent(Eventevent)override{
    if(ContainerBase::OnMouseEvent(event)){
    returntrue;
    }

    if(event.mouse().button!=Mouse::WheelUp&&
    event.mouse().button!=Mouse::WheelDown){
    returnfalse;
    }

    if(!box_.Contain(event.mouse().x,event.mouse().y)){
    returnfalse;
    }

    constintold_selected=*selector_;
    if(event.mouse().button==Mouse::WheelUp){
    MoveSelector(-1);
    }
    if(event.mouse().button==Mouse::WheelDown){
    MoveSelector(+1);
    }
    *selector_=std::max(0,std::min(int(children_.size())-1,*selector_));

    returnold_selected!=*selector_;
    }

    Boxbox_;
    };

    classHorizontalContainer:publicContainerBase{
    public:
    usingContainerBase::ContainerBase;

    ElementOnRender()override{
    Elementselements;
    elements.reserve(children_.size());
    for(auto&it:children_){
    elements.push_back(it->Render());
    }
    if(elements.empty()){
    returntext("Emptycontainer");
    }
    returnhbox(std::move(elements));
    }

    boolEventHandler(Eventevent)override{
    constintold_selected=*selector_;
    if(event==Event::ArrowLeft||event==Event::Character('h')){
    MoveSelector(-1);
    }
    if(event==Event::ArrowRight||event==Event::Character('l')){
    MoveSelector(+1);
    }
    if(event==Event::Tab){
    MoveSelectorWrap(+1);
    }
    if(event==Event::TabReverse){
    MoveSelectorWrap(-1);
    }

    *selector_=std::max(0,std::min(int(children_.size())-1,*selector_));
    returnold_selected!=*selector_;
    }
    };

    classTabContainer:publicContainerBase{
    public:
    usingContainerBase::ContainerBase;

    ElementOnRender()override{
    constComponentactive_child=ActiveChild();
    if(active_child){
    returnactive_child->Render();
    }
    returntext("Emptycontainer");
    }

    boolFocusable()constoverride{
    if(children_.empty()){
    returnfalse;
    }
    returnchildren_[size_t(*selector_)%children_.size()]->Focusable();
    }

    boolOnMouseEvent(Eventevent)override{
    returnActiveChild()&&ActiveChild()->OnEvent(event);
    }
    };

    classStackedContainer:publicContainerBase{
    public:
    explicitStackedContainer(Componentschildren)
    :ContainerBase(std::move(children),nullptr){}

    private:
    ElementOnRender()final{
    Elementselements;
    for(auto&child:children_){
    elements.push_back(child->Render());
    }
    //Reversetheorderoftheelements.
    std::reverse(elements.begin(),elements.end());
    returndbox(std::move(elements));
    }

    boolFocusable()constfinal{
    for(constauto&child:children_){
    if(child->Focusable()){
    returntrue;
    }
    }
    returnfalse;
    }

    ComponentActiveChild()final{
    if(children_.empty()){
    returnnullptr;
    }
    returnchildren_[0];
    }

    voidSetActiveChild(ComponentBase*child)final{
    if(children_.empty()){
    return;
    }

    //Find`child`andputitatthebeginningwithoutchangetheorderofthe
    //otherchildren.
    autoit=
    std::find_if(children_.begin(),children_.end(),
    [child](constComponent&c){returnc.get()==child;});
    if(it==children_.end()){
    return;
    }
    std::rotate(children_.begin(),it,it+1);
    }

    boolOnEvent(Eventevent)final{
    for(auto&child:children_){
    if(child->OnEvent(event)){
    returntrue;
    }
    }
    returnfalse;
    }
    };

    namespaceContainer{

    ///@briefAlistofcomponents,drawnonebyoneverticallyandnavigated
    ///verticallyusingup/downarrowkeyor'j'/'k'keys.
    ///@paramchildrenthelistofcomponents.
    ///@ingroupcomponent
    ///@seeContainerBase
    ///
    ///###Example
    ///
    ///```cpp
    ///autocontainer=Container::Vertical({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///});
    ///```
    ComponentVertical(Componentschildren){
    returnVertical(std::move(children),nullptr);
    }

    ///@briefAlistofcomponents,drawnonebyoneverticallyandnavigated
    ///verticallyusingup/downarrowkeyor'j'/'k'keys.
    ///ThisisusefulforimplementingaMenuforinstance.
    ///@paramchildrenthelistofcomponents.
    ///@paramselectorAreferencetotheindexoftheselectedchildren.
    ///@ingroupcomponent
    ///@seeContainerBase
    ///
    ///###Example
    ///
    ///```cpp
    ///autocontainer=Container::Vertical({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///},&selected_children);
    ///```
    ComponentVertical(Componentschildren,int*selector){
    returnstd::make_shared<VerticalContainer>(std::move(children),selector);
    }

    ///@briefAlistofcomponents,drawnonebyonehorizontallyandnavigated
    ///horizontallyusingleft/rightarrowkeyor'h'/'l'keys.
    ///@paramchildrenthelistofcomponents.
    ///@ingroupcomponent
    ///@seeContainerBase
    ///
    ///###Example
    ///
    ///```cpp
    ///intselected_children=2;
    ///autocontainer=Container::Horizontal({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///});
    ///```
    ComponentHorizontal(Componentschildren){
    returnHorizontal(std::move(children),nullptr);
    }

    ///@briefAlistofcomponents,drawnonebyonehorizontallyandnavigated
    ///horizontallyusingleft/rightarrowkeyor'h'/'l'keys.
    ///@paramchildrenthelistofcomponents.
    ///@paramselectorAreferencetotheindexoftheselectedchildren.
    ///@ingroupcomponent
    ///@seeContainerBase
    ///
    ///###Example
    ///
    ///```cpp
    ///intselected_children=2;
    ///autocontainer=Container::Horizontal({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///},selected_children);
    ///```
    ComponentHorizontal(Componentschildren,int*selector){
    returnstd::make_shared<HorizontalContainer>(std::move(children),selector);
    }

    ///@briefAlistofcomponents,whereonlyoneisdrawnandinteractedwithat
    ///atime.The|selector|givestheindexoftheselectedcomponent.Thisis
    ///usefultoimplementtabs.
    ///@paramchildrenThelistofcomponents.
    ///@paramselectorTheindexofthedrawnchildren.
    ///@ingroupcomponent
    ///@seeContainerBase
    ///
    ///###Example
    ///
    ///```cpp
    ///inttab_drawn=0;
    ///autocontainer=Container::Tab({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///},&tab_drawn);
    ///```
    ComponentTab(Componentschildren,int*selector){
    returnstd::make_shared<TabContainer>(std::move(children),selector);
    }

    ///@briefAlistofcomponentstobestackedontopofeachother.
    ///Eventsarepropagatedtothefirstcomponent,thenthesecondifnot
    ///handled,etc.
    ///Thecomponentsaredrawninthereverseordertheyaregiven.
    ///Whenacomponenttakefocus,itisputatthefront,withoutchangingthe
    ///relativeorderoftheotherelements.
    ///
    ///Thisshouldbeusedwiththe`Window`component.
    ///
    ///@paramchildrenThelistofcomponents.
    ///@ingroupcomponent
    ///@seeWindow
    ///
    ///###Example
    ///
    ///```cpp
    ///autocontainer=Container::Stacked({
    ///children_1,
    ///children_2,
    ///children_3,
    ///children_4,
    ///});
    ///```
    ComponentStacked(Componentschildren){
    returnstd::make_shared<StackedContainer>(std::move(children));
    }

    }//namespaceContainer

    }//namespaceftxui