table.cpp
ftxui/dom/table.hpp
algorithm
initializer_list
memory
utility
vector
ftxui/dom/elements.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/dom/table.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/table.cpp
algorithm
cstddef
cstdint
ftxui/dom/take_any_args.hpp
functional
initializer_list
memory
optional
sstream
string
unordered_map
utility
variant
vector
ftxui

    //Copyright2021ArthurSonzogni.Allrightsreserved.
    //UseofthissourcecodeisgovernedbytheMITlicensethatcanbefoundin
    //theLICENSEfile.
    #include"ftxui/dom/table.hpp"

    #include<algorithm>//formax
    #include<initializer_list>//forinitializer_list
    #include<memory>//forallocator,shared_ptr,allocator_traits<>::value_type
    #include<utility>//formove,swap
    #include<vector>//forvector

    #include"ftxui/dom/elements.hpp"//forElement,operator|,text,separatorCharacter,Elements,BorderStyle,Decorator,emptyElement,size,gridbox,EQUAL,flex,flex_shrink,HEIGHT,WIDTH

    namespaceftxui{
    namespace{

    boolIsCell(intx,inty){
    returnx%2==1&&y%2==1;
    }

    //NOLINTNEXTLINE
    staticstd::stringcharset[6][6]={
    {"┌","┐","└","┘","─","│"},//LIGHT
    {"┏","┓","┗","┛","╍","╏"},//DASHED
    {"┏","┓","┗","┛","━","┃"},//HEAVY
    {"╔","╗","╚","╝","═","║"},//DOUBLE
    {"╭","╮","╰","╯","─","│"},//ROUNDED
    {"","","","","",""},//EMPTY
    };

    intWrap(intinput,intmodulo){
    input%=modulo;
    input+=modulo;
    input%=modulo;
    returninput;
    }

    voidOrder(int&a,int&b){
    if(a>=b){
    std::swap(a,b);
    }
    }

    }//namespace

    ///@briefCreateanemptytable.
    ///@ingroupdom
    Table::Table(){
    Initialize({});
    }

    ///@briefCreateatablefromavectorofvectorofstring.
    ///@paraminputTheinputdata.
    ///@ingroupdom
    Table::Table(std::vector<std::vector<std::string>>input){
    std::vector<std::vector<Element>>output;
    output.reserve(input.size());
    for(auto&row:input){
    output.emplace_back();
    auto&output_row=output.back();
    output_row.reserve(row.size());
    for(auto&cell:row){
    output_row.push_back(text(std::move(cell)));
    }
    }
    Initialize(std::move(output));
    }

    ///@briefCreateatablefromavectorofvectorofElement
    ///@paraminputTheinputelements.
    ///@ingroupdom
    Table::Table(std::vector<std::vector<Element>>input){
    Initialize(std::move(input));
    }

    //@briefCreateatablefromalistoflistofstring.
    //@paraminitTheinputdata.
    //@ingroupdom
    Table::Table(std::initializer_list<std::vector<std::string>>init){
    std::vector<std::vector<Element>>input;
    for(constauto&row:init){
    std::vector<Element>output_row;
    output_row.reserve(row.size());
    for(constauto&cell:row){
    output_row.push_back(text(cell));
    }
    input.push_back(std::move(output_row));
    }
    Initialize(std::move(input));
    }

    //private
    voidTable::Initialize(std::vector<std::vector<Element>>input){
    input_dim_y_=static_cast<int>(input.size());
    input_dim_x_=0;
    for(auto&row:input){
    input_dim_x_=std::max(input_dim_x_,int(row.size()));
    }

    dim_y_=2*input_dim_y_+1;
    dim_x_=2*input_dim_x_+1;

    //Reservespace.
    elements_.resize(dim_y_);
    for(inty=0;y<dim_y_;++y){
    elements_[y].resize(dim_x_);
    }

    //Transfertelements_from|input|toward|elements_|.
    {
    inty=1;
    for(auto&row:input){
    intx=1;
    for(auto&cell:row){
    elements_[y][x]=std::move(cell);
    x+=2;
    }
    y+=2;
    }
    }

    //Addemptyelementfortheborder.
    for(inty=0;y<dim_y_;++y){
    for(intx=0;x<dim_x_;++x){
    auto&element=elements_[y][x];

    if(IsCell(x,y)){
    if(!element){
    element=emptyElement();
    }
    continue;
    }

    element=emptyElement();
    }
    }
    }

    ///@briefSelectarowofthetable.
    ///@paramindexTheindexoftherowtoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectRow(intindex){
    returnSelectRectangle(0,-1,index,index);
    }

    ///@briefSelectarangeofrowsofthetable.
    ///@paramrow_minThefirstrowtoselect.
    ///@paramrow_maxThelastrowtoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectRows(introw_min,introw_max){
    returnSelectRectangle(0,-1,row_min,row_max);
    }

    ///@briefSelectacolumnofthetable.
    ///@paramindexTheindexofthecolumntoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectColumn(intindex){
    returnSelectRectangle(index,index,0,-1);
    }

    ///@briefSelectarangeofcolumnsofthetable.
    ///@paramcolumn_minThefirstcolumntoselect.
    ///@paramcolumn_maxThelastcolumntoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectColumns(intcolumn_min,intcolumn_max){
    returnSelectRectangle(column_min,column_max,0,-1);
    }

    ///@briefSelectacellofthetable.
    ///@paramcolumnThecolumnofthecelltoselect.
    ///@paramrowTherowofthecelltoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectCell(intcolumn,introw){
    returnSelectRectangle(column,column,row,row);
    }

    ///@briefSelectarectangleofthetable.
    ///@paramcolumn_minThefirstcolumntoselect.
    ///@paramcolumn_maxThelastcolumntoselect.
    ///@paramrow_minThefirstrowtoselect.
    ///@paramrow_maxThelastrowtoselect.
    ///@noteYoucanusenegativeindextoselectfromtheend.
    ///@ingroupdom
    TableSelectionTable::SelectRectangle(intcolumn_min,
    intcolumn_max,
    introw_min,
    introw_max){
    column_min=Wrap(column_min,input_dim_x_);
    column_max=Wrap(column_max,input_dim_x_);
    Order(column_min,column_max);
    row_min=Wrap(row_min,input_dim_y_);
    row_max=Wrap(row_max,input_dim_y_);
    Order(row_min,row_max);

    TableSelectionoutput;//NOLINT
    output.table_=this;
    output.x_min_=2*column_min;
    output.x_max_=2*column_max+2;
    output.y_min_=2*row_min;
    output.y_max_=2*row_max+2;
    returnoutput;
    }

    ///@briefSelectallthetable.
    ///@ingroupdom
    TableSelectionTable::SelectAll(){
    TableSelectionoutput;//NOLINT
    output.table_=this;
    output.x_min_=0;
    output.x_max_=dim_x_-1;
    output.y_min_=0;
    output.y_max_=dim_y_-1;
    returnoutput;
    }

    ///@briefRenderthetable.
    ///@returnTherenderedtable.Thisisanelementyoucandraw.
    ///@ingroupdom
    ElementTable::Render(){
    for(inty=0;y<dim_y_;++y){
    for(intx=0;x<dim_x_;++x){
    auto&it=elements_[y][x];

    //Line
    if((x+y)%2==1){
    it=std::move(it)|flex;
    continue;
    }

    //Cells
    if((x%2)==1&&(y%2)==1){
    it=std::move(it)|flex_shrink;
    continue;
    }

    //Corners
    it=std::move(it)|size(WIDTH,EQUAL,0)|size(HEIGHT,EQUAL,0);
    }
    }
    dim_x_=0;
    dim_y_=0;
    returngridbox(std::move(elements_));
    }

    ///@briefApplythe`decorator`totheselection.
    ///Thisdecorateboththecells,thelinesandthecorners.
    ///@paramdecoratorThedecoratortoapply.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::Decorate(Decoratordecorator){
    for(inty=y_min_;y<=y_max_;++y){
    for(intx=x_min_;x<=x_max_;++x){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }

    ///@briefApplythe`decorator`totheselection.
    ///@paramdecoratorThedecoratortoapply.
    ///Thisdecorateonlythecells.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::DecorateCells(Decoratordecorator){
    for(inty=y_min_;y<=y_max_;++y){
    for(intx=x_min_;x<=x_max_;++x){
    if(y%2==1&&x%2==1){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }
    }

    ///@briefApplythe`decorator`totheselection.
    ///Thisdecorateonlythelinesmodulo`modulo`withashiftof`shift`.
    ///@paramdecoratorThedecoratortoapply.
    ///@parammoduloThemoduloofthelinestodecorate.
    ///@paramshiftTheshiftofthelinestodecorate.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::DecorateAlternateColumn(Decoratordecorator,
    intmodulo,
    intshift){
    for(inty=y_min_;y<=y_max_;++y){
    for(intx=x_min_;x<=x_max_;++x){
    if(y%2==1&&(x/2)%modulo==shift){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }
    }

    ///@briefApplythe`decorator`totheselection.
    ///Thisdecorateonlythelinesmodulo`modulo`withashiftof`shift`.
    ///@paramdecoratorThedecoratortoapply.
    ///@parammoduloThemoduloofthelinestodecorate.
    ///@paramshiftTheshiftofthelinestodecorate.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::DecorateAlternateRow(Decoratordecorator,
    intmodulo,
    intshift){
    for(inty=y_min_+1;y<=y_max_-1;++y){
    for(intx=x_min_;x<=x_max_;++x){
    if(y%2==1&&(y/2)%modulo==shift){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }
    }

    ///@briefApplythe`decorator`totheselection.
    ///Thisdecorateonlythecornersmodulo`modulo`withashiftof`shift`.
    ///@paramdecoratorThedecoratortoapply.
    ///@parammoduloThemoduloofthecornerstodecorate.
    ///@paramshiftTheshiftofthecornerstodecorate.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::DecorateCellsAlternateColumn(Decoratordecorator,
    intmodulo,
    intshift){
    for(inty=y_min_;y<=y_max_;++y){
    for(intx=x_min_;x<=x_max_;++x){
    if(y%2==1&&x%2==1&&((x/2)%modulo==shift)){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }
    }

    ///@briefApplythe`decorator`totheselection.
    ///Thisdecorateonlythecornersmodulo`modulo`withashiftof`shift`.
    ///@paramdecoratorThedecoratortoapply.
    ///@parammoduloThemoduloofthecornerstodecorate.
    ///@paramshiftTheshiftofthecornerstodecorate.
    ///@ingroupdom
    //NOLINTNEXTLINE
    voidTableSelection::DecorateCellsAlternateRow(Decoratordecorator,
    intmodulo,
    intshift){
    for(inty=y_min_;y<=y_max_;++y){
    for(intx=x_min_;x<=x_max_;++x){
    if(y%2==1&&x%2==1&&((y/2)%modulo==shift)){
    Element&e=table_->elements_[y][x];
    e=std::move(e)|decorator;
    }
    }
    }
    }

    ///@briefApplya`border`aroundtheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::Border(BorderStyleborder){
    BorderLeft(border);
    BorderRight(border);
    BorderTop(border);
    BorderBottom(border);

    //NOLINTNEXTLINE
    table_->elements_[y_min_][x_min_]=text(charset[border][0])|automerge;
    //NOLINTNEXTLINE
    table_->elements_[y_min_][x_max_]=text(charset[border][1])|automerge;
    //NOLINTNEXTLINE
    table_->elements_[y_max_][x_min_]=text(charset[border][2])|automerge;
    //NOLINTNEXTLINE
    table_->elements_[y_max_][x_max_]=text(charset[border][3])|automerge;
    }

    ///@briefDrawsomeseparatorlinesintheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::Separator(BorderStyleborder){
    for(inty=y_min_+1;y<=y_max_-1;++y){
    for(intx=x_min_+1;x<=x_max_-1;++x){
    if(y%2==0||x%2==0){
    Element&e=table_->elements_[y][x];
    e=(y%2==1)
    ?separatorCharacter(charset[border][5])|automerge//NOLINT
    :separatorCharacter(charset[border][4])|automerge;//NOLINT
    }
    }
    }
    }

    ///@briefDrawsomeverticalseparatorlinesintheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::SeparatorVertical(BorderStyleborder){
    for(inty=y_min_+1;y<=y_max_-1;++y){
    for(intx=x_min_+1;x<=x_max_-1;++x){
    if(x%2==0){
    table_->elements_[y][x]=
    separatorCharacter(charset[border][5])|automerge;//NOLINT
    }
    }
    }
    }

    ///@briefDrawsomehorizontalseparatorlinesintheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::SeparatorHorizontal(BorderStyleborder){
    for(inty=y_min_+1;y<=y_max_-1;++y){
    for(intx=x_min_+1;x<=x_max_-1;++x){
    if(y%2==0){
    table_->elements_[y][x]=
    separatorCharacter(charset[border][4])|automerge;//NOLINT
    }
    }
    }
    }

    ///@briefDrawsomeseparatorlinestotheleftsideoftheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::BorderLeft(BorderStyleborder){
    for(inty=y_min_;y<=y_max_;y++){
    table_->elements_[y][x_min_]=
    separatorCharacter(charset[border][5])|automerge;//NOLINT
    }
    }

    ///@briefDrawsomeseparatorlinestotherightsideoftheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::BorderRight(BorderStyleborder){
    for(inty=y_min_;y<=y_max_;y++){
    table_->elements_[y][x_max_]=
    separatorCharacter(charset[border][5])|automerge;//NOLINT
    }
    }

    ///@briefDrawsomeseparatorlinestothetopsideoftheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::BorderTop(BorderStyleborder){
    for(intx=x_min_;x<=x_max_;x++){
    table_->elements_[y_min_][x]=
    separatorCharacter(charset[border][4])|automerge;//NOLINT
    }
    }

    ///@briefDrawsomeseparatorlinestothebottomsideoftheselection.
    ///@paramborderTheborderstyletoapply.
    ///@ingroupdom
    voidTableSelection::BorderBottom(BorderStyleborder){
    for(intx=x_min_;x<=x_max_;x++){
    table_->elements_[y_max_][x]=
    separatorCharacter(charset[border][4])|automerge;//NOLINT
    }
    }

    }//namespaceftxui