window.cpp
algorithm
ftxui/component/component.hpp
ftxui/component/component_base.hpp
ftxui/component/component_options.hpp
ftxui/component/screen_interactive.hpp
memory
utility
ftxui/dom/elements.hpp
ftxui/dom/node_decorator.hpp
ftxui/screen/color.hpp
ftxui/screen/screen.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/component/receiver.hpp
ftxui/component/screen_interactive.hpp
ftxui/component/task.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/window.cpp
ftxui/dom/node_decorator.hpp
algorithm
atomic
chrono
condition_variable
cstddef
cstdint
ftxui/dom/take_any_args.hpp
functional
memory
mutex
optional
queue
sstream
string
thread
unordered_map
utility
variant
vector
ftxui
NOMINMAX

    //Copyright2023ArthurSonzogni.Allrightsreserved.
    //UseofthissourcecodeisgovernedbytheMITlicensethatcanbefoundin
    //theLICENSEfile.
    #defineNOMINMAX
    #include<algorithm>
    #include<ftxui/component/component.hpp>
    #include<ftxui/component/component_base.hpp>
    #include<ftxui/component/component_options.hpp>
    #include<ftxui/component/screen_interactive.hpp>//forScreenInteractive
    #include<memory>
    #include<utility>
    #include"ftxui/dom/elements.hpp"//fortext,window,hbox,vbox,size,clear_under,reflect,emptyElement
    #include"ftxui/dom/node_decorator.hpp"//forNodeDecorator
    #include"ftxui/screen/color.hpp"//forColor
    #include"ftxui/screen/screen.hpp"//forScreen

    namespaceftxui{

    namespace{

    DecoratorPositionAndSize(intleft,inttop,intwidth,intheight){
    return[=](Elementelement){
    element|=size(WIDTH,EQUAL,width);
    element|=size(HEIGHT,EQUAL,height);

    autopadding_left=emptyElement()|size(WIDTH,EQUAL,left);
    autopadding_top=emptyElement()|size(HEIGHT,EQUAL,top);

    returnvbox({
    padding_top,
    hbox({
    padding_left,
    element,
    }),
    });
    };
    }

    classResizeDecorator:publicNodeDecorator{
    public:
    ResizeDecorator(Elementchild,
    boolresize_left,
    boolresize_right,
    boolresize_top,
    boolresize_down,
    Colorcolor)
    :NodeDecorator(std::move(child)),
    color_(color),
    resize_left_(resize_left),
    resize_right_(resize_right),
    resize_top_(resize_top),
    resize_down_(resize_down){}

    voidRender(Screen&screen)override{
    NodeDecorator::Render(screen);

    if(resize_left_){
    for(inty=box_.y_min;y<=box_.y_max;++y){
    auto&cell=screen.PixelAt(box_.x_min,y);
    cell.foreground_color=color_;
    cell.automerge=false;
    }
    }
    if(resize_right_){
    for(inty=box_.y_min;y<=box_.y_max;++y){
    auto&cell=screen.PixelAt(box_.x_max,y);
    cell.foreground_color=color_;
    cell.automerge=false;
    }
    }
    if(resize_top_){
    for(intx=box_.x_min;x<=box_.x_max;++x){
    auto&cell=screen.PixelAt(x,box_.y_min);
    cell.foreground_color=color_;
    cell.automerge=false;
    }
    }
    if(resize_down_){
    for(intx=box_.x_min;x<=box_.x_max;++x){
    auto&cell=screen.PixelAt(x,box_.y_max);
    cell.foreground_color=color_;
    cell.automerge=false;
    }
    }
    }

    Colorcolor_;
    constboolresize_left_;
    constboolresize_right_;
    constboolresize_top_;
    constboolresize_down_;
    };

    ElementDefaultRenderState(constWindowRenderState&state){
    Elementelement=state.inner;
    if(!state.active){
    element|=dim;
    }

    element=window(text(state.title),element);
    element|=clear_under;

    constColorcolor=Color::Red;

    element=std::make_shared<ResizeDecorator>(//
    element,//
    state.hover_left,//
    state.hover_right,//
    state.hover_top,//
    state.hover_down,//
    color//
    );

    returnelement;
    }

    classWindowImpl:publicComponentBase,publicWindowOptions{
    public:
    explicitWindowImpl(WindowOptionsoption):WindowOptions(std::move(option)){
    if(!inner){
    inner=Make<ComponentBase>();
    }
    Add(inner);
    }

    private:
    ElementOnRender()final{
    autoelement=ComponentBase::Render();

    constboolcaptureable=
    captured_mouse_||ScreenInteractive::Active()->CaptureMouse();

    constWindowRenderStatestate={
    element,
    title(),
    Active(),
    drag_,
    resize_left_||resize_right_||resize_down_||resize_top_,
    (resize_left_hover_||resize_left_)&&captureable,
    (resize_right_hover_||resize_right_)&&captureable,
    (resize_top_hover_||resize_top_)&&captureable,
    (resize_down_hover_||resize_down_)&&captureable,
    };

    element=render?render(state):DefaultRenderState(state);

    //Positionandrecordthedrawnareaofthewindow.
    element|=reflect(box_window_);
    element|=PositionAndSize(left(),top(),width(),height());
    element|=reflect(box_);

    returnelement;
    }

    boolOnEvent(Eventevent)final{
    if(ComponentBase::OnEvent(event)){
    returntrue;
    }

    if(!event.is_mouse()){
    returnfalse;
    }

    mouse_hover_=box_window_.Contain(event.mouse().x,event.mouse().y);

    resize_down_hover_=false;
    resize_top_hover_=false;
    resize_left_hover_=false;
    resize_right_hover_=false;

    if(mouse_hover_){
    resize_left_hover_=event.mouse().x==left()+box_.x_min;
    resize_right_hover_=
    event.mouse().x==left()+width()-1+box_.x_min;
    resize_top_hover_=event.mouse().y==top()+box_.y_min;
    resize_down_hover_=event.mouse().y==top()+height()-1+box_.y_min;

    //Applythecomponentoptions:
    resize_top_hover_&=resize_top();
    resize_left_hover_&=resize_left();
    resize_down_hover_&=resize_down();
    resize_right_hover_&=resize_right();
    }

    if(captured_mouse_){
    if(event.mouse().motion==Mouse::Released){
    captured_mouse_=nullptr;
    returntrue;
    }

    if(resize_left_){
    width()=left()+width()-event.mouse().x+box_.x_min;
    left()=event.mouse().x-box_.x_min;
    }

    if(resize_right_){
    width()=event.mouse().x-resize_start_x-box_.x_min;
    }

    if(resize_top_){
    height()=top()+height()-event.mouse().y+box_.y_min;
    top()=event.mouse().y-box_.y_min;
    }

    if(resize_down_){
    height()=event.mouse().y-resize_start_y-box_.y_min;
    }

    if(drag_){
    left()=event.mouse().x-drag_start_x-box_.x_min;
    top()=event.mouse().y-drag_start_y-box_.y_min;
    }

    //Clampthewindowsize.
    width()=std::max<int>(width(),static_cast<int>(title().size()+2));
    height()=std::max<int>(height(),2);

    returntrue;
    }

    resize_left_=false;
    resize_right_=false;
    resize_top_=false;
    resize_down_=false;

    if(!mouse_hover_){
    returnfalse;
    }

    if(!CaptureMouse(event)){
    returntrue;
    }

    if(event.mouse().button!=Mouse::Left){
    returntrue;
    }
    if(event.mouse().motion!=Mouse::Pressed){
    returntrue;
    }

    TakeFocus();

    captured_mouse_=CaptureMouse(event);
    if(!captured_mouse_){
    returntrue;
    }

    resize_left_=resize_left_hover_;
    resize_right_=resize_right_hover_;
    resize_top_=resize_top_hover_;
    resize_down_=resize_down_hover_;

    resize_start_x=event.mouse().x-width()-box_.x_min;
    resize_start_y=event.mouse().y-height()-box_.y_min;
    drag_start_x=event.mouse().x-left()-box_.x_min;
    drag_start_y=event.mouse().y-top()-box_.y_min;

    //Dragonlyifwearenotresizeingaborderyet:
    drag_=!resize_right_&&!resize_down_&&!resize_top_&&!resize_left_;
    returntrue;
    }

    Boxbox_;
    Boxbox_window_;

    CapturedMousecaptured_mouse_;
    intdrag_start_x=0;
    intdrag_start_y=0;
    intresize_start_x=0;
    intresize_start_y=0;

    boolmouse_hover_=false;
    booldrag_=false;
    boolresize_top_=false;
    boolresize_left_=false;
    boolresize_down_=false;
    boolresize_right_=false;

    boolresize_top_hover_=false;
    boolresize_left_hover_=false;
    boolresize_down_hover_=false;
    boolresize_right_hover_=false;
    };

    }//namespace

    ///@briefAdraggeable/resizeablewindow.Tousemultipleofthem,theymust
    ///bestackedusing`Container::Stacked({...})`component;
    ///
    ///@paramoptionAstructholdingeveryparameters.
    ///@ingroupcomponent
    ///@seeWindow
    ///
    ///###Example
    ///
    ///```cpp
    ///autowindow_1=Window({
    ///.inner=DummyWindowContent(),
    ///.title="Firstwindow",
    ///});
    ///
    ///autowindow_2=Window({
    ///.inner=DummyWindowContent(),
    ///.title="Secondwindow",
    ///});
    ///
    ///autocontainer=Container::Stacked({
    ///window_1,
    ///window_2,
    ///});
    ///```
    ComponentWindow(WindowOptionsoption){
    returnMake<WindowImpl>(std::move(option));
    }

    };//namespaceftxui