border.cpp
algorithm
array
ftxui/screen/color.hpp
memory
optional
string
utility
ftxui/dom/elements.hpp
ftxui/dom/node.hpp
ftxui/dom/requirement.hpp
ftxui/screen/box.hpp
ftxui/screen/pixel.hpp
ftxui/screen/screen.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/dom/border.cpp
algorithm
array
cstddef
cstdint
ftxui/dom/take_any_args.hpp
functional
memory
optional
sstream
string
unordered_map
utility
variant
vector
ftxui

    //Copyright2020ArthurSonzogni.Allrightsreserved.
    //UseofthissourcecodeisgovernedbytheMITlicensethatcanbefoundin
    //theLICENSEfile.
    #include<algorithm>//formax
    #include<array>//forarray
    #include<ftxui/screen/color.hpp>//forColor
    #include<memory>//forallocator,make_shared,__shared_ptr_access
    #include<optional>//foroptional,nullopt
    #include<string>//forbasic_string,string
    #include<utility>//formove

    #include"ftxui/dom/elements.hpp"//forunpack,Element,Decorator,BorderStyle,ROUNDED,borderStyled,Elements,DASHED,DOUBLE,EMPTY,HEAVY,LIGHT,border,borderDashed,borderDouble,borderEmpty,borderHeavy,borderLight,borderRounded,borderWith,window
    #include"ftxui/dom/node.hpp"//forNode,Elements
    #include"ftxui/dom/requirement.hpp"//forRequirement
    #include"ftxui/screen/box.hpp"//forBox
    #include"ftxui/screen/pixel.hpp"//forPixel
    #include"ftxui/screen/screen.hpp"//forPixel,Screen

    namespaceftxui{

    namespace{
    usingCharset=std::array<std::string,6>;//NOLINT
    usingCharsets=std::array<Charset,6>;//NOLINT
    //NOLINTNEXTLINE
    staticCharsetssimple_border_charset={
    Charset{"┌","┐","└","┘","─","│"},//LIGHT
    Charset{"┏","┓","┗","┛","╍","╏"},//DASHED
    Charset{"┏","┓","┗","┛","━","┃"},//HEAVY
    Charset{"╔","╗","╚","╝","═","║"},//DOUBLE
    Charset{"╭","╮","╰","╯","─","│"},//ROUNDED
    Charset{"","","","","",""},//EMPTY
    };

    //Forreference,hereisthecharsetfornormalborder:
    classBorder:publicNode{
    public:
    Border(Elementschildren,
    BorderStylestyle,
    std::optional<Color>foreground_color=std::nullopt)
    :Node(std::move(children)),
    charset_(simple_border_charset[style])//NOLINT
    ,
    foreground_color_(foreground_color){}//NOLINT

    constCharset&charset_;//NOLINT
    std::optional<Color>foreground_color_;

    voidComputeRequirement()override{
    Node::ComputeRequirement();
    requirement_=children_[0]->requirement();
    requirement_.min_x+=2;
    requirement_.min_y+=2;
    if(children_.size()==2){
    requirement_.min_x=
    std::max(requirement_.min_x,children_[1]->requirement().min_x+2);
    }
    requirement_.focused.box.x_min++;
    requirement_.focused.box.x_max++;
    requirement_.focused.box.y_min++;
    requirement_.focused.box.y_max++;
    }

    voidSetBox(Boxbox)override{
    Node::SetBox(box);
    if(children_.size()==2){
    Boxtitle_box;
    title_box.x_min=box.x_min+1;
    title_box.x_max=std::min(box.x_max-1,
    box.x_min+children_[1]->requirement().min_x);
    title_box.y_min=box.y_min;
    title_box.y_max=box.y_min;
    children_[1]->SetBox(title_box);
    }
    box.x_min++;
    box.x_max--;
    box.y_min++;
    box.y_max--;
    children_[0]->SetBox(box);
    }

    voidRender(Screen&screen)override{
    //Drawcontent.
    children_[0]->Render(screen);

    //Drawtheborder.
    if(box_.x_min>=box_.x_max||box_.y_min>=box_.y_max){
    return;
    }

    screen.at(box_.x_min,box_.y_min)=charset_[0];//NOLINT
    screen.at(box_.x_max,box_.y_min)=charset_[1];//NOLINT
    screen.at(box_.x_min,box_.y_max)=charset_[2];//NOLINT
    screen.at(box_.x_max,box_.y_max)=charset_[3];//NOLINT

    for(intx=box_.x_min+1;x<box_.x_max;++x){
    Pixel&p1=screen.PixelAt(x,box_.y_min);
    Pixel&p2=screen.PixelAt(x,box_.y_max);
    p1.character=charset_[4];//NOLINT
    p2.character=charset_[4];//NOLINT
    p1.automerge=true;
    p2.automerge=true;
    }
    for(inty=box_.y_min+1;y<box_.y_max;++y){
    Pixel&p3=screen.PixelAt(box_.x_min,y);
    Pixel&p4=screen.PixelAt(box_.x_max,y);
    p3.character=charset_[5];//NOLINT
    p4.character=charset_[5];//NOLINT
    p3.automerge=true;
    p4.automerge=true;
    }

    //Drawtitle.
    if(children_.size()==2){
    children_[1]->Render(screen);
    }

    //Drawthebordercolor.
    if(foreground_color_){
    for(intx=box_.x_min;x<=box_.x_max;++x){
    screen.PixelAt(x,box_.y_min).foreground_color=*foreground_color_;
    screen.PixelAt(x,box_.y_max).foreground_color=*foreground_color_;
    }
    for(inty=box_.y_min;y<=box_.y_max;++y){
    screen.PixelAt(box_.x_min,y).foreground_color=*foreground_color_;
    screen.PixelAt(box_.x_max,y).foreground_color=*foreground_color_;
    }
    }
    }
    };

    //Forreference,hereisthecharsetfornormalborder:
    classBorderPixel:publicNode{
    public:
    BorderPixel(Elementschildren,Pixelpixel)
    :Node(std::move(children)),pixel_(std::move(pixel)){}

    private:
    Pixelpixel_;

    voidComputeRequirement()override{
    Node::ComputeRequirement();
    requirement_=children_[0]->requirement();
    requirement_.min_x+=2;
    requirement_.min_y+=2;
    if(children_.size()==2){
    requirement_.min_x=
    std::max(requirement_.min_x,children_[1]->requirement().min_x+2);
    }

    requirement_.focused.box.Shift(1,1);
    }

    voidSetBox(Boxbox)override{
    Node::SetBox(box);
    if(children_.size()==2){
    Boxtitle_box;
    title_box.x_min=box.x_min+1;
    title_box.x_max=box.x_max-1;
    title_box.y_min=box.y_min;
    title_box.y_max=box.y_min;
    children_[1]->SetBox(title_box);
    }
    box.x_min++;
    box.x_max--;
    box.y_min++;
    box.y_max--;
    children_[0]->SetBox(box);
    }

    voidRender(Screen&screen)override{
    //Drawcontent.
    children_[0]->Render(screen);

    //Drawtheborder.
    if(box_.x_min>=box_.x_max||box_.y_min>=box_.y_max){
    return;
    }

    screen.PixelAt(box_.x_min,box_.y_min)=pixel_;
    screen.PixelAt(box_.x_max,box_.y_min)=pixel_;
    screen.PixelAt(box_.x_min,box_.y_max)=pixel_;
    screen.PixelAt(box_.x_max,box_.y_max)=pixel_;

    for(intx=box_.x_min+1;x<box_.x_max;++x){
    screen.PixelAt(x,box_.y_min)=pixel_;
    screen.PixelAt(x,box_.y_max)=pixel_;
    }
    for(inty=box_.y_min+1;y<box_.y_max;++y){
    screen.PixelAt(box_.x_min,y)=pixel_;
    screen.PixelAt(box_.x_max,y)=pixel_;
    }
    }
    };
    }//namespace

    ///@briefDrawaborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderEmpty
    ///@seeborderRounded
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'border'asafunction...
    ///Elementdocument=border(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|border;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///┌───────────┐
    ///│Theelement│
    ///└───────────┘
    ///```
    Elementborder(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),ROUNDED);
    }

    ///@briefSameasborderbutwithaconstantPixelaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    DecoratorborderWith(constPixel&pixel){
    return[pixel](Elementchild){
    returnstd::make_shared<BorderPixel>(unpack(std::move(child)),pixel);
    };
    }

    ///@briefSameasborderbutwithdifferentstyles.
    ///@ingroupdom
    ///@seeborder
    DecoratorborderStyled(BorderStylestyle){
    return[style](Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),style);
    };
    }

    ///@briefSameasborderbutwithaforegroundcolor.
    ///@ingroupdom
    ///@seeborder
    DecoratorborderStyled(Colorforeground_color){
    return[foreground_color](Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),ROUNDED,
    foreground_color);
    };
    }

    ///@briefSameasborderbutwithaforegroundcolorandadifferentstyle
    ///@ingroupdom
    ///@seeborder
    DecoratorborderStyled(BorderStylestyle,Colorforeground_color){
    return[style,foreground_color](Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),style,
    foreground_color);
    };
    }

    ///@briefDrawadashedborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderDash'asafunction...
    ///Elementdocument=borderDash(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderDAsh;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓
    ///╏Theelement╏
    ///┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛
    ///```
    ElementborderDashed(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),DASHED);
    }

    ///@briefDrawalightborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderLight'asafunction...
    ///Elementdocument=borderLight(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderLight;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///┌──────────────┐
    ///│Theelement│
    ///└──────────────┘
    ///```
    ElementborderLight(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),LIGHT);
    }

    ///@briefDrawaheavyborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderHeavy'asafunction...
    ///Elementdocument=borderHeavy(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderHeavy;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///┏━━━━━━━━━━━━━━┓
    ///┃Theelement┃
    ///┗━━━━━━━━━━━━━━┛
    ///```
    ElementborderHeavy(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),HEAVY);
    }

    ///@briefDrawadoubleborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderDouble'asafunction...
    ///Elementdocument=borderDouble(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderDouble;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///╔══════════════╗
    ///║Theelement║
    ///╚══════════════╝
    ///```
    ElementborderDouble(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),DOUBLE);
    }

    ///@briefDrawaroundedborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderRounded'asafunction...
    ///Elementdocument=borderRounded(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderRounded;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///╭──────────────╮
    ///│Theelement│
    ///╰──────────────╯
    ///```
    ElementborderRounded(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),ROUNDED);
    }

    ///@briefDrawanemptyborderaroundtheelement.
    ///@ingroupdom
    ///@seeborder
    ///@seeborderLight
    ///@seeborderDashed
    ///@seeborderDouble
    ///@seeborderHeavy
    ///@seeborderRounded
    ///@seeborderEmpty
    ///@seeborderStyled
    ///@seeborderWith
    ///
    ///Addaborderaroundanelement
    ///
    ///###Example
    ///
    ///```cpp
    /////Use'borderRounded'asafunction...
    ///Elementdocument=borderRounded(text("Theelement"));
    ///
    /////...Orasa'pipe'.
    ///Elementdocument=text("Theelement")|borderRounded;
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///
    ///Theelement
    ///
    ///```
    ElementborderEmpty(Elementchild){
    returnstd::make_shared<Border>(unpack(std::move(child)),EMPTY);
    }

    ///@briefDrawwindowwithatitleandaborderaroundtheelement.
    ///@paramtitleThetitleofthewindow.
    ///@paramcontentTheelementtobewrapped.
    ///@paramborderThestyleoftheborder.DefaultisROUNDED.
    ///@ingroupdom
    ///@seeborder
    ///
    ///###Example
    ///
    ///```cpp
    ///Elementdocument=window(text("Title"),
    ///text("content")
    ///);
    ///
    /////Withspecifyingborder
    ///Elementdocument=window(text("Title"),
    ///text("content"),
    ///ROUNDED
    ///);
    ///```
    ///
    ///###Output
    ///
    ///```bash
    ///┌Title──┐
    ///│content│
    ///└───────┘
    ///```
    Elementwindow(Elementtitle,Elementcontent,BorderStyleborder){
    returnstd::make_shared<Border>(unpack(std::move(content),std::move(title)),
    border);
    }
    }//namespaceftxui