diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index b97dc39f..dceb7613 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -56,7 +56,7 @@ void Menu::CheckClickAndPerformMenuSelect(Crawler*game){ } void Menu::HoverMenuSelect(Crawler*game){ - if(selection==vi2d{-1,-1})return; + if(selection==vi2d{-1,-1}||buttons[selection.y][selection.x]->disabled)return; if(buttons[selection.y][selection.x]->draggable) if(buttonHoldTime<"ThemeGlobal.MenuHoldTime"_F)CheckClickAndPerformMenuSelect(game); else{ @@ -67,7 +67,7 @@ void Menu::HoverMenuSelect(Crawler*game){ } void Menu::MenuSelect(Crawler*game){ - if(selection==vi2d{-1,-1})return; + if(selection==vi2d{-1,-1}||buttons[selection.y][selection.x]->disabled)return; buttons[selection.y][selection.x]->onClick(MenuFuncData{*this,game,buttons[selection.y][selection.x]}); if(buttons[selection.y][selection.x]->menuDest!=MenuType::ENUM_END){ if(stack.size()<32){ @@ -90,7 +90,9 @@ void Menu::Update(Crawler*game){ for(auto&key:buttons){ for(auto&button:key.second){ - button->hovered=false; + if(!button->disabled){ + button->hovered=false; + } } } if(!MOUSE_NAVIGATION){ @@ -99,12 +101,14 @@ void Menu::Update(Crawler*game){ for(auto&key:buttons){ int index=0; for(auto&button:key.second){ - if(geom2d::overlaps(geom2d::rect{button->rect.pos+pos,button->rect.size},game->GetMousePos())){ - button->hovered=true; - selection.y=key.first; - selection.x=index; + if(!button->disabled){ + if(button->GetHoverState(game)){ + button->hovered=true; + selection.y=key.first; + selection.x=index; + } + index++; } - index++; } } } @@ -132,13 +136,13 @@ void Menu::Update(Crawler*game){ for(auto&key:buttons){ for(auto&button:key.second){ if(button->renderInMain){ - button->Update(game); + button->_Update(game); } } } for(auto&component:displayComponents){ if(component->renderInMain){ - component->Update(game); + component->_Update(game); } } }; @@ -157,13 +161,13 @@ void Menu::Draw(Crawler*game){ for(auto&key:buttons){ for(auto&button:key.second){ if(button->renderInMain){ - button->Draw(game,{0,0},this==Menu::stack.back()); + button->_Draw(game,{0,0},this==Menu::stack.back()); } } } for(auto&component:displayComponents){ if(component->renderInMain){ - component->Draw(game,{0,0},this==Menu::stack.back()); + component->_Draw(game,{0,0},this==Menu::stack.back()); } } game->SetPixelMode(prevMode); @@ -173,13 +177,13 @@ void Menu::Draw(Crawler*game){ for(auto&key:buttons){ for(auto&button:key.second){ if(button->renderInMain){ - button->DrawDecal(game,pos,this==Menu::stack.back()); + button->_DrawDecal(game,pos,this==Menu::stack.back()); } } } for(auto&component:displayComponents){ if(component->renderInMain){ - component->DrawDecal(game,pos,this==Menu::stack.back()); + component->_DrawDecal(game,pos,this==Menu::stack.back()); } } @@ -220,6 +224,7 @@ void Menu::OpenMenu(MenuType menu){ } void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){ + vi2d prevSelection=selection; if(game->GetKey(RIGHT).bPressed){ if(selection==vi2d{-1,-1})return; MOUSE_NAVIGATION=false; @@ -345,6 +350,10 @@ void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){ buttonHoldTime=0; } } + if(prevSelection!=selection){ + if(selection!=vi2d{-1,-1}&&buttons[selection.y][selection.x]->disabled)selection=prevSelection; + // If the new selection of a button on this frame is disabled for some reason, we need to go back to what we had selected before. + } } void Menu::DrawScaledWindowBorder(Crawler*game,vf2d menuPos){ diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp index aafd12a9..49fcb70c 100644 --- a/Crawler/MenuComponent.cpp +++ b/Crawler/MenuComponent.cpp @@ -15,6 +15,12 @@ void MenuComponent::Update(Crawler*game){ } } +void MenuComponent::_Update(Crawler*game){ + if(!disabled){ + Update(game); + } +} + void MenuComponent::Draw(Crawler*game,vf2d parentPos,bool focused){ game->FillRect(rect.pos+parentPos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)*(focused?1:"ThemeGlobal.MenuUnfocusedColorMult"_F)); if(border){ @@ -23,12 +29,37 @@ void MenuComponent::Draw(Crawler*game,vf2d parentPos,bool focused){ game->DrawStringProp(rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label,focused?WHITE:WHITE*"ThemeGlobal.MenuUnfocusedColorMult"_F); } +void MenuComponent::_Draw(Crawler*game,vf2d parentPos,bool focused){ + if(!disabled){ + Draw(game,parentPos,focused); + } +} + void MenuComponent::DrawDecal(Crawler*game,vf2d parentPos,bool focused){} +void MenuComponent::_DrawDecal(Crawler*game,vf2d parentPos,bool focused){ + if(!disabled){ + DrawDecal(game,parentPos,focused); + } +} + MenuComponent*MenuComponent::PickUpDraggableItem(){ return nullptr; } bool MenuComponent::DropDraggableItem(MenuComponent*draggable){ return false; +} + +bool MenuComponent::GetHoverState(Crawler*game){ + if(parentComponent!=nullptr){ + return parentComponent->GetHoverState(game,this); + }else{ + vf2d parentWindowPos=Menu::menus[parentMenu]->pos; + return geom2d::overlaps(geom2d::rect{rect.pos+parentWindowPos,rect.size},game->GetMousePos()); + } +} + +bool MenuComponent::GetHoverState(Crawler*game,MenuComponent*child){ + return false; } \ No newline at end of file diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h index 3077c689..823844a4 100644 --- a/Crawler/MenuComponent.h +++ b/Crawler/MenuComponent.h @@ -8,6 +8,7 @@ class MenuComponent{ MenuType menuDest; private: float hoverEffect=0; + virtual bool GetHoverState(Crawler*game); protected: geom2d::rectrect; std::string label; @@ -15,15 +16,21 @@ protected: bool draggable=false; MenuFunc onClick; MenuType parentMenu=MenuType::ENUM_END; + MenuComponent*parentComponent=nullptr; bool hovered=false; bool selectable=true; + bool disabled=false; //If set to true, this component will not be rendered or updated. bool renderInMain=true; //If set to false, this component is the responsibility of some other windowing system and won't be rendered or updated via the main window loop. -public: - MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuFunc onClick,bool selectable=true); - MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuType menuDest,MenuFunc onClick,bool selectable=true); virtual void Update(Crawler*game); virtual void Draw(Crawler*game,vf2d parentPos,bool focused); virtual void DrawDecal(Crawler*game,vf2d parentPos,bool focused); + virtual bool GetHoverState(Crawler*game,MenuComponent*child); +public: + MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuFunc onClick,bool selectable=true); + MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuType menuDest,MenuFunc onClick,bool selectable=true); + void _Update(Crawler*game); + void _Draw(Crawler*game,vf2d parentPos,bool focused); + void _DrawDecal(Crawler*game,vf2d parentPos,bool focused); //We picked up a draggable component, we should make a copy and return it here. If a nullptr is returned here, the pickup is not allowed. //WARNING!!! This allocates a brand new component when successful!!! Be prepared to clear it! virtual MenuComponent*PickUpDraggableItem(); diff --git a/Crawler/ScrollableWindowComponent.h b/Crawler/ScrollableWindowComponent.h index d043afbc..96028941 100644 --- a/Crawler/ScrollableWindowComponent.h +++ b/Crawler/ScrollableWindowComponent.h @@ -9,6 +9,10 @@ protected: std::vectorcomponents; vf2d scrollOffset{}; geom2d::rectbounds; +private: + inline bool OnScreen(MenuComponent*component){ + return geom2d::overlaps(rect,geom2d::rect{component->rect.pos+scrollOffset,component->rect.size}); + } public: inline ScrollableWindowComponent(MenuType parent,geom2d::rectrect,Decal*icon,MenuFunc onClick) :MenuComponent(parent,rect,"",onClick,false){ @@ -17,8 +21,18 @@ public: protected: virtual inline void Update(Crawler*game)override{ MenuComponent::Update(game); + + if(game->GetMouseWheel()!=0){ + if(game->GetMouseWheel()>0){ + scrollOffset.y-=4; + }else{ + scrollOffset.y+=4; + } + } + for(MenuComponent*component:components){ - component->Update(game); + component->disabled=!OnScreen(component); + component->_Update(game); } } virtual inline void Draw(Crawler*game,vf2d parentPos,bool focused)override{ @@ -27,7 +41,7 @@ protected: game->SetDrawTarget(r.Sprite()); game->Clear(BLANK); for(MenuComponent*component:components){ - component->Draw(game,scrollOffset,focused); + component->_Draw(game,scrollOffset,focused); } game->SetDrawTarget(prevDrawTarget); game->DrawSprite(parentPos,r.Sprite()); @@ -36,13 +50,17 @@ protected: MenuComponent::DrawDecal(game,parentPos,focused); game->DrawRectDecal(parentPos,rect.size); for(MenuComponent*component:components){ - component->DrawDecal(game,parentPos+scrollOffset,focused); + component->_DrawDecal(game,parentPos+scrollOffset,focused); } } + virtual bool GetHoverState(Crawler*game,MenuComponent*child)override{ + return geom2d::overlaps(geom2d::rect{Menu::menus[parentMenu]->pos+child->rect.pos+scrollOffset,child->rect.size},game->GetMousePos()); + } public: void inline AddComponent(Menu*parentMenu,std::string key,MenuComponent*button){ components.push_back(button); button->renderInMain=false; //Now we are in control! + button->parentComponent=this; if(button->rect.pos.xrect.pos.x; diff --git a/Crawler/Version.h b/Crawler/Version.h index 929ddfcd..2d201c32 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 1972 +#define VERSION_BUILD 1988 #define stringify(a) stringify_(a) #define stringify_(a) #a