examples/component/homescreen.cpp

    //Copyright2020ArthurSonzogni.Allrightsreserved.
    //UseofthissourcecodeisgovernedbytheMITlicensethatcanbefoundin
    //theLICENSEfile.
    #include<stddef.h>//forsize_t
    #include<array>//forarray
    #include<atomic>//foratomic
    #include<chrono>//foroperator""s,chrono_literals
    #include<cmath>//forsin
    #include<functional>//forref,reference_wrapper,function
    #include<memory>//forallocator,shared_ptr,__shared_ptr_access
    #include<string>//forstring,basic_string,char_traits,operator+,to_string
    #include<thread>//forsleep_for,thread
    #include<utility>//formove
    #include<vector>//forvector

    #include"../dom/color_info_sorted_2d.ipp"//forColorInfoSorted2D
    #include"ftxui/component/component.hpp"//forCheckbox,Renderer,Horizontal,Vertical,Input,Menu,Radiobox,ResizableSplitLeft,Tab
    #include"ftxui/component/component_base.hpp"//forComponentBase,Component
    #include"ftxui/component/component_options.hpp"//forMenuOption,InputOption
    #include"ftxui/component/event.hpp"//forEvent,Event::Custom
    #include"ftxui/component/screen_interactive.hpp"//forComponent,ScreenInteractive
    #include"ftxui/dom/elements.hpp"//fortext,color,operator|,bgcolor,filler,Element,vbox,size,hbox,separator,flex,window,graph,EQUAL,paragraph,WIDTH,hcenter,Elements,bold,vscroll_indicator,HEIGHT,flexbox,hflow,border,frame,flex_grow,gauge,paragraphAlignCenter,paragraphAlignJustify,paragraphAlignLeft,paragraphAlignRight,dim,spinner,LESS_THAN,center,yframe,GREATER_THAN
    #include"ftxui/dom/flexbox_config.hpp"//forFlexboxConfig
    #include"ftxui/screen/color.hpp"//forColor,Color::BlueLight,Color::RedLight,Color::Black,Color::Blue,Color::Cyan,Color::CyanLight,Color::GrayDark,Color::GrayLight,Color::Green,Color::GreenLight,Color::Magenta,Color::MagentaLight,Color::Red,Color::White,Color::Yellow,Color::YellowLight,Color::Default,Color::Palette256,ftxui
    #include"ftxui/screen/color_info.hpp"//forColorInfo
    #include"ftxui/screen/terminal.hpp"//forSize,Dimensions

    usingnamespaceftxui;

    intmain(){
    autoscreen=ScreenInteractive::Fullscreen();

    //---------------------------------------------------------------------------
    //HTOP
    //---------------------------------------------------------------------------
    intshift=0;

    automy_graph=[&shift](intwidth,intheight){
    std::vector<int>output(width);
    for(inti=0;i<width;++i){
    floatv=0.5f;
    v+=0.1f*sin((i+shift)*0.1f);
    v+=0.2f*sin((i+shift+10)*0.15f);
    v+=0.1f*sin((i+shift)*0.03f);
    v*=height;
    output[i]=(int)v;
    }
    returnoutput;
    };

    autohtop=Renderer([&]{
    autofrequency=vbox({
    text("Frequency[Mhz]")|hcenter,
    hbox({
    vbox({
    text("2400"),
    filler(),
    text("1200"),
    filler(),
    text("0"),
    }),
    graph(std::ref(my_graph))|flex,
    })|flex,
    });

    autoutilization=vbox({
    text("Utilization[%]")|hcenter,
    hbox({
    vbox({
    text("100"),
    filler(),
    text("50"),
    filler(),
    text("0"),
    }),
    graph(std::ref(my_graph))|color(Color::RedLight),
    })|flex,
    });

    autoram=vbox({
    text("Ram[Mo]")|hcenter,
    hbox({
    vbox({
    text("8192"),
    filler(),
    text("4096"),
    filler(),
    text("0"),
    }),
    graph(std::ref(my_graph))|color(Color::BlueLight),
    })|flex,
    });

    returnhbox({
    vbox({
    frequency|flex,
    separator(),
    utilization|flex,
    })|flex,
    separator(),
    ram|flex,
    })|
    flex;
    });

    //---------------------------------------------------------------------------
    //Compiler
    //---------------------------------------------------------------------------

    conststd::vector<std::string>compiler_entries={
    "gcc",
    "clang",
    "emcc",
    "game_maker",
    "Adacompilers",
    "ALGOL60compilers",
    "ALGOL68compilers",
    "Assemblers(Intel*86)",
    "Assemblers(Motorola68*)",
    "Assemblers(ZilogZ80)",
    "Assemblers(other)",
    "BASICCompilers",
    "BASICinterpreters",
    "Batchcompilers",
    "Ccompilers",
    "Source-to-sourcecompilers",
    "C++compilers",
    "C#compilers",
    "COBOLcompilers",
    "CommonLispcompilers",
    "Dcompilers",
    "DIBOL/DBLcompilers",
    "ECMAScriptinterpreters",
    "Eiffelcompilers",
    "Fortrancompilers",
    "Gocompilers",
    "Haskellcompilers",
    "Javacompilers",
    "Pascalcompilers",
    "PerlInterpreters",
    "PHPcompilers",
    "PL/Icompilers",
    "Pythoncompilers",
    "Schemecompilersandinterpreters",
    "Smalltalkcompilers",
    "TclInterpreters",
    "VMSInterpreters",
    "RexxInterpreters",
    "CLIcompilers",
    };

    intcompiler_selected=0;
    Componentcompiler=Radiobox(&compiler_entries,&compiler_selected);

    std::array<std::string,8>options_label={
    "-Wall",
    "-Werror",
    "-lpthread",
    "-O3",
    "-Wabi-tag",
    "-Wno-class-conversion",
    "-Wcomma-subscript",
    "-Wno-conversion-null",
    };
    std::array<bool,8>options_state={
    false,false,false,false,false,false,false,false,
    };

    std::vector<std::string>input_entries;
    intinput_selected=0;
    Componentinput=Menu(&input_entries,&input_selected);

    autoinput_option=InputOption();
    std::stringinput_add_content;
    input_option.on_enter=[&]{
    input_entries.push_back(input_add_content);
    input_add_content="";
    };
    Componentinput_add=Input(&input_add_content,"inputfiles",input_option);

    std::stringexecutable_content_="";
    Componentexecutable_=Input(&executable_content_,"executable");

    Componentflags=Container::Vertical({
    Checkbox(&options_label[0],&options_state[0]),
    Checkbox(&options_label[1],&options_state[1]),
    Checkbox(&options_label[2],&options_state[2]),
    Checkbox(&options_label[3],&options_state[3]),
    Checkbox(&options_label[4],&options_state[4]),
    Checkbox(&options_label[5],&options_state[5]),
    Checkbox(&options_label[6],&options_state[6]),
    Checkbox(&options_label[7],&options_state[7]),
    });

    autocompiler_component=Container::Horizontal({
    compiler,
    flags,
    Container::Vertical({
    executable_,
    Container::Horizontal({
    input_add,
    input,
    }),
    }),
    });

    autorender_command=[&]{
    Elementsline;
    //Compiler
    line.push_back(text(compiler_entries[compiler_selected])|bold);
    //flags
    for(inti=0;i<8;++i){
    if(options_state[i]){
    line.push_back(text(""));
    line.push_back(text(options_label[i])|dim);
    }
    }
    //Executable
    if(!executable_content_.empty()){
    line.push_back(text("-o")|bold);
    line.push_back(text(executable_content_)|color(Color::BlueLight)|
    bold);
    }
    //Input
    for(auto&it:input_entries){
    line.push_back(text(""+it)|color(Color::RedLight));
    }
    returnline;
    };

    autocompiler_renderer=Renderer(compiler_component,[&]{
    autocompiler_win=window(text("Compiler"),
    compiler->Render()|vscroll_indicator|frame);
    autoflags_win=
    window(text("Flags"),flags->Render()|vscroll_indicator|frame);
    autoexecutable_win=window(text("Executable:"),executable_->Render());
    autoinput_win=
    window(text("Input"),hbox({
    vbox({
    hbox({
    text("Add:"),
    input_add->Render(),
    })|size(WIDTH,EQUAL,20)|
    size(HEIGHT,EQUAL,1),
    filler(),
    }),
    separator(),
    input->Render()|vscroll_indicator|frame|
    size(HEIGHT,EQUAL,3)|flex,
    }));
    returnvbox({
    hbox({
    compiler_win,
    flags_win,
    vbox({
    executable_win|size(WIDTH,EQUAL,20),
    input_win|size(WIDTH,EQUAL,60),
    }),
    filler(),
    })|size(HEIGHT,LESS_THAN,8),
    hflow(render_command())|flex_grow,
    })|
    flex_grow;
    });

    //---------------------------------------------------------------------------
    //Spinner
    //---------------------------------------------------------------------------
    autospinner_tab_renderer=Renderer([&]{
    Elementsentries;
    for(inti=0;i<22;++i){
    entries.push_back(spinner(i,shift/2)|bold|
    size(WIDTH,GREATER_THAN,2)|border);
    }
    returnhflow(std::move(entries));
    });

    //---------------------------------------------------------------------------
    //Colors
    //---------------------------------------------------------------------------
    autocolor_tab_renderer=Renderer([]{
    autobasic_color_display=
    vbox({
    text("16colorpalette:"),
    separator(),
    hbox({
    vbox({
    color(Color::Default,text("Default")),
    color(Color::Black,text("Black")),
    color(Color::GrayDark,text("GrayDark")),
    color(Color::GrayLight,text("GrayLight")),
    color(Color::White,text("White")),
    color(Color::Blue,text("Blue")),
    color(Color::BlueLight,text("BlueLight")),
    color(Color::Cyan,text("Cyan")),
    color(Color::CyanLight,text("CyanLight")),
    color(Color::Green,text("Green")),
    color(Color::GreenLight,text("GreenLight")),
    color(Color::Magenta,text("Magenta")),
    color(Color::MagentaLight,text("MagentaLight")),
    color(Color::Red,text("Red")),
    color(Color::RedLight,text("RedLight")),
    color(Color::Yellow,text("Yellow")),
    color(Color::YellowLight,text("YellowLight")),
    }),
    vbox({
    bgcolor(Color::Default,text("Default")),
    bgcolor(Color::Black,text("Black")),
    bgcolor(Color::GrayDark,text("GrayDark")),
    bgcolor(Color::GrayLight,text("GrayLight")),
    bgcolor(Color::White,text("White")),
    bgcolor(Color::Blue,text("Blue")),
    bgcolor(Color::BlueLight,text("BlueLight")),
    bgcolor(Color::Cyan,text("Cyan")),
    bgcolor(Color::CyanLight,text("CyanLight")),
    bgcolor(Color::Green,text("Green")),
    bgcolor(Color::GreenLight,text("GreenLight")),
    bgcolor(Color::Magenta,text("Magenta")),
    bgcolor(Color::MagentaLight,text("MagentaLight")),
    bgcolor(Color::Red,text("Red")),
    bgcolor(Color::RedLight,text("RedLight")),
    bgcolor(Color::Yellow,text("Yellow")),
    bgcolor(Color::YellowLight,text("YellowLight")),
    }),
    }),
    })|
    border;

    autopalette_256_color_display=text("256colorspalette:");
    {
    std::vector<std::vector<ColorInfo>>info_columns=ColorInfoSorted2D();
    Elementscolumns;
    for(auto&column:info_columns){
    Elementscolumn_elements;
    for(auto&it:column){
    column_elements.push_back(
    text("")|bgcolor(Color(Color::Palette256(it.index_256))));
    }
    columns.push_back(hbox(std::move(column_elements)));
    }
    palette_256_color_display=vbox({
    palette_256_color_display,
    separator(),
    vbox(columns),
    })|
    border;
    }

    //Truecolordisplay.
    autotrue_color_display=text("TrueColors:24bits:");
    {
    intsaturation=255;
    Elementsarray;
    for(intvalue=0;value<255;value+=16){
    Elementsline;
    for(inthue=0;hue<255;hue+=6){
    line.push_back(text("▀")//
    |color(Color::HSV(hue,saturation,value))//
    |bgcolor(Color::HSV(hue,saturation,value+8)));
    }
    array.push_back(hbox(std::move(line)));
    }
    true_color_display=vbox({
    true_color_display,
    separator(),
    vbox(std::move(array)),
    })|
    border;
    }

    returnflexbox(
    {
    basic_color_display,
    palette_256_color_display,
    true_color_display,
    },
    FlexboxConfig().SetGap(1,1));
    });

    //---------------------------------------------------------------------------
    //Gauges
    //---------------------------------------------------------------------------
    autorender_gauge=[&shift](intdelta){
    floatprogress=(shift+delta)%500/500.f;
    returnhbox({
    text(std::to_string(int(progress*100))+"%")|
    size(WIDTH,EQUAL,5),
    gauge(progress),
    });
    };

    autogauge_component=Renderer([render_gauge]{
    returnvbox({
    render_gauge(0)|color(Color::Black),
    render_gauge(100)|color(Color::GrayDark),
    render_gauge(50)|color(Color::GrayLight),
    render_gauge(6894)|color(Color::White),
    separator(),
    render_gauge(6841)|color(Color::Blue),
    render_gauge(9813)|color(Color::BlueLight),
    render_gauge(98765)|color(Color::Cyan),
    render_gauge(98)|color(Color::CyanLight),
    render_gauge(9846)|color(Color::Green),
    render_gauge(1122)|color(Color::GreenLight),
    render_gauge(84)|color(Color::Magenta),
    render_gauge(645)|color(Color::MagentaLight),
    render_gauge(568)|color(Color::Red),
    render_gauge(2222)|color(Color::RedLight),
    render_gauge(220)|color(Color::Yellow),
    render_gauge(348)|color(Color::YellowLight),
    });
    });

    //---------------------------------------------------------------------------
    //Paragraph
    //---------------------------------------------------------------------------
    automake_box=[](size_tdimx,size_tdimy){
    std::stringtitle=std::to_string(dimx)+"x"+std::to_string(dimy);
    returnwindow(text(title)|hcenter|bold,
    text("content")|hcenter|dim)|
    size(WIDTH,EQUAL,dimx)|size(HEIGHT,EQUAL,dimy);
    };

    autoparagraph_renderer_left=Renderer([&]{
    std::stringstr=
    "LoremIpsumissimplydummytextoftheprintingandtypesetting"
    "industry.\nLoremIpsumhasbeentheindustry'sstandarddummytext"
    "eversincethe1500s,whenanunknownprintertookagalleyoftype"
    "andscrambledittomakeatypespecimenbook.";
    returnvbox({
    window(text("Alignleft:"),paragraphAlignLeft(str)),
    window(text("Aligncenter:"),paragraphAlignCenter(str)),
    window(text("Alignright:"),paragraphAlignRight(str)),
    window(text("Alignjustify:"),paragraphAlignJustify(str)),
    window(text("Sidebyside"),hbox({
    paragraph(str),
    separator(),
    paragraph(str),
    })),
    window(text("Elementswithdifferentsize:"),
    flexbox({
    make_box(10,5),
    make_box(9,4),
    make_box(8,4),
    make_box(6,3),
    make_box(10,5),
    make_box(9,4),
    make_box(8,4),
    make_box(6,3),
    make_box(10,5),
    make_box(9,4),
    make_box(8,4),
    make_box(6,3),
    })),
    })|
    vscroll_indicator|yframe|flex;
    });

    autoparagraph_renderer_right=Renderer([]{
    returnparagraph("<---Thisverticalbarisresizableusingthemouse")|
    center;
    });

    intparagraph_renderer_split_position=Terminal::Size().dimx/2;
    autoparagraph_renderer_group=
    ResizableSplitLeft(paragraph_renderer_left,paragraph_renderer_right,
    &paragraph_renderer_split_position);
    autoparagraph_renderer_group_renderer=
    Renderer(paragraph_renderer_group,
    [&]{returnparagraph_renderer_group->Render();});

    //---------------------------------------------------------------------------
    //Tabs
    //---------------------------------------------------------------------------

    inttab_index=0;
    std::vector<std::string>tab_entries={
    "htop","color","spinner","gauge","compiler","paragraph",
    };
    autotab_selection=
    Menu(&tab_entries,&tab_index,MenuOption::HorizontalAnimated());
    autotab_content=Container::Tab(
    {
    htop,
    color_tab_renderer,
    spinner_tab_renderer,
    gauge_component,
    compiler_renderer,
    paragraph_renderer_group_renderer,
    },
    &tab_index);

    autoexit_button=
    Button("Exit",[&]{screen.Exit();},ButtonOption::Animated());

    automain_container=Container::Vertical({
    Container::Horizontal({
    tab_selection,
    exit_button,
    }),
    tab_content,
    });

    automain_renderer=Renderer(main_container,[&]{
    returnvbox({
    text("FTXUIDemo")|bold|hcenter,
    hbox({
    tab_selection->Render()|flex,
    exit_button->Render(),
    }),
    tab_content->Render()|flex,
    });
    });

    std::atomic<bool>refresh_ui_continue=true;
    std::threadrefresh_ui([&]{
    while(refresh_ui_continue){
    usingnamespacestd::chrono_literals;
    std::this_thread::sleep_for(0.05s);
    //The|shift|variablebelongtothemainthread.`screen.Post(task)`
    //willexecutetheupdateonthethreadwhere|screen|lives(e.g.the
    //mainthread).Using`screen.Post(task)`isthreadsafe.
    screen.Post([&]{shift++;});
    //Afterupdatingthestate,requestanewframetobedrawn.Thisisdone
    //bysimulatinganew"custom"eventtobehandled.
    screen.Post(Event::Custom);
    }
    });

    screen.Loop(main_renderer);
    refresh_ui_continue=false;
    refresh_ui.join();

    return0;
    }