|
|
|
@ -12,6 +12,10 @@ protected: |
|
|
|
|
MenuComponent*upButton=nullptr; |
|
|
|
|
MenuComponent*downButton=nullptr; |
|
|
|
|
geom2d::rect<float>bounds; //It's for the scrollbar.
|
|
|
|
|
float scrollBarHeight=0; |
|
|
|
|
float scrollBarTop=0; |
|
|
|
|
bool scrollBarSelected=false; |
|
|
|
|
float scrollBarHoverTime=0; |
|
|
|
|
private: |
|
|
|
|
inline bool OnScreen(MenuComponent*component){ |
|
|
|
|
return geom2d::overlaps(rect,geom2d::rect<float>{component->rect.pos+V(A::SCROLL_OFFSET),component->rect.size}); |
|
|
|
@ -27,15 +31,43 @@ public: |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
virtual inline void AfterCreate()override{ |
|
|
|
|
upButton=new MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[](MenuFuncData dat){std::cout<<"Clicked"<<std::endl;}); |
|
|
|
|
downButton=new MenuComponent(parentMenu,{rect.size-vf2d{12,12},{12,12}},"v",[](MenuFuncData dat){}); |
|
|
|
|
Menu::menus[parentMenu]->AddComponent("scrollableWindowButton"+upButton->rect.pos.str()+"_"+upButton->rect.size.str(),upButton); |
|
|
|
|
Menu::menus[parentMenu]->AddComponent("scrollableWindowButton"+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton); |
|
|
|
|
upButton=new MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;}); |
|
|
|
|
downButton=new MenuComponent(parentMenu,{rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;}); |
|
|
|
|
//Let's use the internal name of this component to add unique names for sub-components.
|
|
|
|
|
Menu::menus[parentMenu]->AddComponent(name+upButton->rect.pos.str()+"_"+upButton->rect.size.str(),upButton);
|
|
|
|
|
Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton); |
|
|
|
|
} |
|
|
|
|
protected: |
|
|
|
|
virtual inline void Update(Crawler*game)override{ |
|
|
|
|
MenuComponent::Update(game); |
|
|
|
|
|
|
|
|
|
vf2d windowAbsPos=Menu::menus[parentMenu]->pos+rect.pos; |
|
|
|
|
|
|
|
|
|
bool mouseOverScrollbar=geom2d::overlaps(geom2d::rect<float>(windowAbsPos+vf2d{rect.size.x-12,scrollBarTop+12},{12,scrollBarHeight}),game->GetMousePos()); |
|
|
|
|
|
|
|
|
|
if(mouseOverScrollbar||scrollBarSelected){ |
|
|
|
|
scrollBarHoverTime=std::min(scrollBarHoverTime+game->GetElapsedTime(),"ThemeGlobal.HighlightTime"_F); |
|
|
|
|
if(game->GetMouse(0).bPressed){ |
|
|
|
|
scrollBarSelected=true; |
|
|
|
|
} |
|
|
|
|
if(game->GetMouse(0).bReleased){ |
|
|
|
|
scrollBarSelected=false; |
|
|
|
|
} |
|
|
|
|
if(scrollBarSelected){ |
|
|
|
|
float spaceBetweenTopAndBottomArrows=rect.size.y-24; |
|
|
|
|
float viewHeight=rect.size.y; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float totalContentHeight=bounds.size.y; |
|
|
|
|
float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); |
|
|
|
|
//The scroll amount moves centered on the position the mouse is at.
|
|
|
|
|
float newScrollbarTop=(game->GetMousePos().y-windowAbsPos.y-12)-scrollBarHeight/2; |
|
|
|
|
V(A::SCROLL_OFFSET).y=(-newScrollbarTop+1)/scrollBarScale; |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
|
scrollBarHoverTime=std::max(scrollBarHoverTime-game->GetElapsedTime(),0.f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(game->GetMouseWheel()!=0){ |
|
|
|
|
if(game->GetMouseWheel()>0){ |
|
|
|
|
V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuScrollWheelSpeed"_I; |
|
|
|
@ -44,10 +76,19 @@ protected: |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
V(A::SCROLL_OFFSET).y=std::clamp(V(A::SCROLL_OFFSET).y,-(bounds.size.y-rect.size.y),0.f); |
|
|
|
|
|
|
|
|
|
for(MenuComponent*component:components){ |
|
|
|
|
component->disabled=!OnScreen(component); |
|
|
|
|
component->_Update(game); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upButton->disabled=false; |
|
|
|
|
downButton->disabled=false; |
|
|
|
|
if(geom2d::contains(rect,bounds)){//This means we have no reason to show a scrollbar.
|
|
|
|
|
upButton->disabled=true; |
|
|
|
|
downButton->disabled=true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
virtual inline void Draw(Crawler*game,vf2d parentPos,bool focused)override{ |
|
|
|
|
MenuComponent::Draw(game,parentPos,focused); |
|
|
|
@ -60,15 +101,28 @@ protected: |
|
|
|
|
game->SetDrawTarget(prevDrawTarget); |
|
|
|
|
game->DrawSprite(parentPos,r.Sprite()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline void DrawScrollbar(Crawler*game,vf2d parentPos,bool focused){ |
|
|
|
|
float spaceBetweenTopAndBottomArrows=rect.size.y-24; |
|
|
|
|
float viewHeight=rect.size.y; |
|
|
|
|
float totalContentHeight=bounds.size.y; |
|
|
|
|
float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); |
|
|
|
|
scrollBarHeight=viewHeight*scrollBarScale-1; |
|
|
|
|
scrollBarTop=-V(A::SCROLL_OFFSET).y*scrollBarScale+1; |
|
|
|
|
|
|
|
|
|
float focusedWindowColorMult=(focused?1:"ThemeGlobal.MenuUnfocusedColorMult"_F); |
|
|
|
|
|
|
|
|
|
game->FillRectDecal(rect.pos+parentPos+vf2d{rect.size.x-13,scrollBarTop+12},{12,scrollBarHeight},PixelLerp(Menu::GetCurrentTheme().GetButtonCol(),Menu::GetCurrentTheme().GetHighlightCol(),scrollBarHoverTime/"ThemeGlobal.HighlightTime"_F)*focusedWindowColorMult); |
|
|
|
|
game->DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-13,scrollBarTop+12},{12,scrollBarHeight},WHITE*focusedWindowColorMult); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{ |
|
|
|
|
MenuComponent::DrawDecal(game,parentPos,focused); |
|
|
|
|
game->DrawRectDecal(rect.pos+parentPos,rect.size); |
|
|
|
|
for(MenuComponent*component:components){ |
|
|
|
|
component->_DrawDecal(game,rect.pos+parentPos+V(A::SCROLL_OFFSET),focused); |
|
|
|
|
} |
|
|
|
|
game->DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-12,0},{12,12}); |
|
|
|
|
game->DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-12,12},{12,rect.size.y-24}); |
|
|
|
|
game->DrawRectDecal(rect.pos+parentPos+rect.size-vf2d{12,12},{12,12}); |
|
|
|
|
DrawScrollbar(game,parentPos,focused); |
|
|
|
|
} |
|
|
|
|
virtual bool GetHoverState(Crawler*game,MenuComponent*child)override{ |
|
|
|
|
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos+V(A::SCROLL_OFFSET),child->rect.size},game->GetMousePos()); |
|
|
|
|