Auto targeting a component when navigating/selecting in a ScrollableWindowComponent using gamepad/keyboard controls. Added analog stick navigation to load file menu.
This commit is contained in:
parent
df08aa9936
commit
df10dc43a8
@ -695,6 +695,7 @@
|
|||||||
<Text Include="assets\config\gfx\backdrops.txt" />
|
<Text Include="assets\config\gfx\backdrops.txt" />
|
||||||
<Text Include="assets\config\gfx\gfx.txt" />
|
<Text Include="assets\config\gfx\gfx.txt" />
|
||||||
<Text Include="assets\config\gfx\themes.txt" />
|
<Text Include="assets\config\gfx\themes.txt" />
|
||||||
|
<Text Include="assets\config\Interface.txt" />
|
||||||
<Text Include="assets\config\items\Accessories.txt" />
|
<Text Include="assets\config\items\Accessories.txt" />
|
||||||
<Text Include="assets\config\items\Equipment.txt" />
|
<Text Include="assets\config\items\Equipment.txt" />
|
||||||
<Text Include="assets\config\items\ItemCategory.txt" />
|
<Text Include="assets\config\items\ItemCategory.txt" />
|
||||||
|
|||||||
@ -864,6 +864,9 @@
|
|||||||
<Text Include="Chapter_1_2nd_Boss.txt">
|
<Text Include="Chapter_1_2nd_Boss.txt">
|
||||||
<Filter>Documentation\Mechanics</Filter>
|
<Filter>Documentation\Mechanics</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text Include="assets\config\Interface.txt">
|
||||||
|
<Filter>Configurations</Filter>
|
||||||
|
</Text>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="assets\heart.ico">
|
<Image Include="assets\heart.ico">
|
||||||
|
|||||||
@ -62,6 +62,9 @@ bool Input::Pressed(){
|
|||||||
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bPressed)inputPressed=true;
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bPressed)inputPressed=true;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case ANALOG:{
|
||||||
|
//An analog input can never be "pressed". No-op.
|
||||||
|
}break;
|
||||||
default:{
|
default:{
|
||||||
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
||||||
}
|
}
|
||||||
@ -88,6 +91,9 @@ bool Input::Held(){
|
|||||||
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bHeld)inputHeld=true;
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bHeld)inputHeld=true;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case ANALOG:{
|
||||||
|
//An analog input can never be "held". No-op.
|
||||||
|
}break;
|
||||||
default:{
|
default:{
|
||||||
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
||||||
}
|
}
|
||||||
@ -114,6 +120,9 @@ bool Input::Released(){
|
|||||||
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bReleased)inputReleased=true;
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bReleased)inputReleased=true;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case ANALOG:{
|
||||||
|
//An analog input can never be "released". No-op.
|
||||||
|
}break;
|
||||||
default:{
|
default:{
|
||||||
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
||||||
}
|
}
|
||||||
@ -139,6 +148,11 @@ float Input::Analog(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case KEY:
|
||||||
|
case MOUSE:
|
||||||
|
case CONTROLLER:{
|
||||||
|
//Doesn't return analog inputs. No-op.
|
||||||
|
}break;
|
||||||
default:{
|
default:{
|
||||||
ERR("Invalid Control Scheme detected for analog controls! We shouldn't be here!! Type is "<<type);
|
ERR("Invalid Control Scheme detected for analog controls! We shouldn't be here!! Type is "<<type);
|
||||||
}
|
}
|
||||||
@ -181,6 +195,14 @@ const bool InputGroup::Released()const{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float InputGroup::Analog()const{
|
||||||
|
for(Input input:keys){
|
||||||
|
float analogVal=input.Analog();
|
||||||
|
if(analogVal!=0.f)return analogVal;
|
||||||
|
}
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
std::string InputGroup::GetDisplayName(){
|
std::string InputGroup::GetDisplayName(){
|
||||||
std::string combinationDisplay="";
|
std::string combinationDisplay="";
|
||||||
for(Input input:keys){
|
for(Input input:keys){
|
||||||
|
|||||||
@ -80,6 +80,7 @@ public:
|
|||||||
const bool Pressed()const;
|
const bool Pressed()const;
|
||||||
const bool Held()const;
|
const bool Held()const;
|
||||||
const bool Released()const;
|
const bool Released()const;
|
||||||
|
const float Analog()const;
|
||||||
std::string GetDisplayName();
|
std::string GetDisplayName();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -60,8 +60,13 @@ void Menu::InitializeLoadGameWindow(){
|
|||||||
Component<MenuComponent>(type,"Go Back Button")->Click();
|
Component<MenuComponent>(type,"Go Back Button")->Click();
|
||||||
}}},
|
}}},
|
||||||
{game->KEY_SCROLL,{"Scroll Up/Down",[](MenuType type){
|
{game->KEY_SCROLL,{"Scroll Up/Down",[](MenuType type){
|
||||||
auto&scrollWindow=Component<ScrollableWindowComponent>(type,"Game Files List");
|
auto scrollWindow=Component<ScrollableWindowComponent>(type,"Game Files List");
|
||||||
scrollWindow->SetScrollAmount(scrollWindow->GetScrollAmount()+game->KEY_SCROLL.Analog()*game->GetElapsedTime()*"Interface.AnalogScrollSpeed"_F);
|
scrollWindow->SetScrollAmount(scrollWindow->GetScrollAmount()-vf2d{0,game->KEY_SCROLL.Analog()*game->GetElapsedTime()*"Interface.AnalogScrollSpeed"_F});
|
||||||
|
for(auto component:scrollWindow->GetComponents()){
|
||||||
|
if(geom2d::overlaps(scrollWindow->GetPos()+scrollWindow->GetSize()/2,geom2d::rect<float>{component.lock()->GetPos(),component.lock()->GetSize()})){
|
||||||
|
Menu::menus[type]->SetSelection(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
}}},
|
}}},
|
||||||
}
|
}
|
||||||
,{ //Button Navigation Rules
|
,{ //Button Navigation Rules
|
||||||
|
|||||||
@ -297,7 +297,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
std::weak_ptr<MenuComponent>prevSelection=selection;
|
std::weak_ptr<MenuComponent>prevSelection=selection;
|
||||||
|
|
||||||
for(auto&[input,data]:inputGroups){
|
for(auto&[input,data]:inputGroups){
|
||||||
if(input.Released()){
|
if(input.Released()||input.Analog()!=0.f){
|
||||||
SetMouseNavigation(false);
|
SetMouseNavigation(false);
|
||||||
auto&action=data.second;
|
auto&action=data.second;
|
||||||
if(std::holds_alternative<ButtonName>(action))Component<MenuComponent>(type,std::get<ButtonName>(action))->Click();
|
if(std::holds_alternative<ButtonName>(action))Component<MenuComponent>(type,std::get<ButtonName>(action))->Click();
|
||||||
@ -641,6 +641,11 @@ void Menu::SetSelection(std::weak_ptr<MenuComponent>button){
|
|||||||
!button.lock()->parentComponent.expired()&&navigationGroups.count(button.lock()->parentComponent.lock()->GetName())){
|
!button.lock()->parentComponent.expired()&&navigationGroups.count(button.lock()->parentComponent.lock()->GetName())){
|
||||||
keyboardSelection=button;
|
keyboardSelection=button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!UsingMouseNavigation()&&!button.lock()->parentComponent.expired()){
|
||||||
|
auto scrollWindow=button.lock()->parentComponent.lock();
|
||||||
|
scrollWindow->HandleOutsideDisabledButtonSelection(Menu::menus[button.lock()->parentMenu]->components[button.lock()->GetName()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::SetSelection(std::string_view button){
|
void Menu::SetSelection(std::string_view button){
|
||||||
@ -649,6 +654,11 @@ void Menu::SetSelection(std::string_view button){
|
|||||||
!selection.lock()->parentComponent.expired()&&navigationGroups.count(selection.lock()->parentComponent.lock()->GetName())){
|
!selection.lock()->parentComponent.expired()&&navigationGroups.count(selection.lock()->parentComponent.lock()->GetName())){
|
||||||
keyboardSelection=selection;
|
keyboardSelection=selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!UsingMouseNavigation()&&!selection.lock()->parentComponent.expired()){
|
||||||
|
auto scrollWindow=selection.lock()->parentComponent.lock();
|
||||||
|
scrollWindow->HandleOutsideDisabledButtonSelection(Menu::menus[selection.lock()->parentMenu]->components[selection.lock()->GetName()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::SetSelection(std::variant<std::string,std::weak_ptr<MenuComponent>>button){
|
void Menu::SetSelection(std::variant<std::string,std::weak_ptr<MenuComponent>>button){
|
||||||
|
|||||||
@ -127,7 +127,7 @@ protected:
|
|||||||
virtual void OnHover();
|
virtual void OnHover();
|
||||||
public:
|
public:
|
||||||
MenuType parentMenu=MenuType::ENUM_END;
|
MenuType parentMenu=MenuType::ENUM_END;
|
||||||
std::weak_ptr<MenuComponent>parentComponent{};
|
std::weak_ptr<ScrollableWindowComponent>parentComponent{};
|
||||||
MenuComponent(geom2d::rect<float>rect,std::string label,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE);
|
MenuComponent(geom2d::rect<float>rect,std::string label,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE);
|
||||||
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE);
|
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE);
|
||||||
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,vf2d labelScaling,ButtonAttr attributes=ButtonAttr::NONE);
|
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,vf2d labelScaling,ButtonAttr attributes=ButtonAttr::NONE);
|
||||||
|
|||||||
@ -54,7 +54,8 @@ protected:
|
|||||||
float scrollBarTop=0;
|
float scrollBarTop=0;
|
||||||
bool scrollBarSelected=false;
|
bool scrollBarSelected=false;
|
||||||
float scrollBarHoverTime=0;
|
float scrollBarHoverTime=0;
|
||||||
vf2d scrollOffset;
|
vf2d scrollOffset{};
|
||||||
|
vf2d targetScrollOffset{};
|
||||||
protected:
|
protected:
|
||||||
inline bool OnScreen(std::weak_ptr<MenuComponent>component){
|
inline bool OnScreen(std::weak_ptr<MenuComponent>component){
|
||||||
return geom2d::overlaps(geom2d::rect<float>{{},rect.size},geom2d::rect<float>{component.lock()->rect.pos+vf2d{2,2},component.lock()->rect.size-vf2d{2,2}});
|
return geom2d::overlaps(geom2d::rect<float>{{},rect.size},geom2d::rect<float>{component.lock()->rect.pos+vf2d{2,2},component.lock()->rect.size-vf2d{2,2}});
|
||||||
@ -86,13 +87,14 @@ public:
|
|||||||
CalculateBounds();
|
CalculateBounds();
|
||||||
}
|
}
|
||||||
virtual inline void SetScrollAmount(vf2d scrollOffset){
|
virtual inline void SetScrollAmount(vf2d scrollOffset){
|
||||||
this->scrollOffset=scrollOffset;
|
this->targetScrollOffset=scrollOffset;
|
||||||
for(std::weak_ptr<MenuComponent>component:components){
|
|
||||||
component.lock()->rect.pos=component.lock()->originalPos+scrollOffset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
virtual inline vf2d GetScrollAmount(){
|
virtual inline vf2d GetScrollAmount(){
|
||||||
return scrollOffset;
|
return targetScrollOffset;
|
||||||
|
}
|
||||||
|
virtual bool GetHoverState(AiL*game,MenuComponent*child)override{
|
||||||
|
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos,rect.size},game->GetMousePos())&& //Make sure the mouse is inside the parent window component first....
|
||||||
|
geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos,child->rect.size},game->GetMousePos());
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual inline void AfterCreate()override{
|
virtual inline void AfterCreate()override{
|
||||||
@ -141,6 +143,10 @@ protected:
|
|||||||
scrollBarHoverTime=std::max(scrollBarHoverTime-game->GetElapsedTime(),0.f);
|
scrollBarHoverTime=std::max(scrollBarHoverTime-game->GetElapsedTime(),0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(std::weak_ptr<MenuComponent>component:components){
|
||||||
|
component.lock()->rect.pos=component.lock()->originalPos+targetScrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
if(game->GetMouseWheel()!=0){
|
if(game->GetMouseWheel()!=0){
|
||||||
if(game->GetMouseWheel()>0){
|
if(game->GetMouseWheel()>0){
|
||||||
SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuScrollWheelSpeed"_F});
|
SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuScrollWheelSpeed"_F});
|
||||||
@ -150,8 +156,10 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(bounds.size.y-rect.size.y>0){
|
if(bounds.size.y-rect.size.y>0){
|
||||||
|
scrollOffset.y=std::clamp(GetScrollAmount().y,-(bounds.size.y-rect.size.y),0.f);
|
||||||
SetScrollAmount({GetScrollAmount().x,std::clamp(GetScrollAmount().y,-(bounds.size.y-rect.size.y),0.f)});
|
SetScrollAmount({GetScrollAmount().x,std::clamp(GetScrollAmount().y,-(bounds.size.y-rect.size.y),0.f)});
|
||||||
}else{
|
}else{
|
||||||
|
scrollOffset.y=0;
|
||||||
SetScrollAmount({GetScrollAmount().x,0});
|
SetScrollAmount({GetScrollAmount().x,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,10 +203,6 @@ protected:
|
|||||||
DrawScrollbar(window,{},focused);
|
DrawScrollbar(window,{},focused);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual bool GetHoverState(AiL*game,MenuComponent*child)override{
|
|
||||||
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos,rect.size},game->GetMousePos())&& //Make sure the mouse is inside the parent window component first....
|
|
||||||
geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos,child->rect.size},game->GetMousePos());
|
|
||||||
}
|
|
||||||
//Calculates the bounds of all components.
|
//Calculates the bounds of all components.
|
||||||
inline void CalculateBounds(){
|
inline void CalculateBounds(){
|
||||||
bounds={};
|
bounds={};
|
||||||
@ -228,7 +232,7 @@ public:
|
|||||||
std::shared_ptr<T> _AddComponent(std::string key,std::shared_ptr<T>button){
|
std::shared_ptr<T> _AddComponent(std::string key,std::shared_ptr<T>button){
|
||||||
components.push_back(button);
|
components.push_back(button);
|
||||||
button->renderInMain=false; //Now we are in control!
|
button->renderInMain=false; //Now we are in control!
|
||||||
button->parentComponent=Menu::menus[parentMenu]->components[this->GetName()];
|
button->parentComponent=DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(Menu::menus[parentMenu]->components[this->GetName()]);
|
||||||
button->disabled=disabled;
|
button->disabled=disabled;
|
||||||
|
|
||||||
CalculateBounds();
|
CalculateBounds();
|
||||||
@ -244,7 +248,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual inline bool HandleOutsideDisabledButtonSelection(std::weak_ptr<MenuComponent>disabledButton)override{
|
virtual inline bool HandleOutsideDisabledButtonSelection(std::weak_ptr<MenuComponent>disabledButton)override{
|
||||||
//Set the offset so the center is highlighted by this button.
|
//Set the offset so the center is highlighted by this button.
|
||||||
SetScrollAmount(vf2d{GetScrollAmount().x,-disabledButton.lock()->rect.pos.y+disabledButton.lock()->rect.size.y});
|
SetScrollAmount(vf2d{GetScrollAmount().x,GetScrollAmount().y-disabledButton.lock()->rect.pos.y+disabledButton.lock()->rect.size.y});
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
virtual void Cleanup()override{}
|
virtual void Cleanup()override{}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
January 1st
|
January 1st
|
||||||
===========
|
===========
|
||||||
Fix Listeners so they do not leak! (Add a proper listener class and have all listeners inherit from it.)
|
|
||||||
The Hub / NPC Interactions
|
The Hub / NPC Interactions
|
||||||
Settings Menu
|
Settings Menu
|
||||||
- Any settings should be saved to the save file!
|
- Any settings should be saved to the save file!
|
||||||
@ -12,7 +11,6 @@ Settings Menu
|
|||||||
-We have to save keybinds to the save file.
|
-We have to save keybinds to the save file.
|
||||||
|
|
||||||
- Fix Stage Completed screen, item displays can hit the scrollbar.
|
- Fix Stage Completed screen, item displays can hit the scrollbar.
|
||||||
- Monster spawn list is not populated in Emscripten?
|
|
||||||
|
|
||||||
January 31st
|
January 31st
|
||||||
============
|
============
|
||||||
@ -26,15 +24,16 @@ Story proofreading/correcting/storyboarding
|
|||||||
|
|
||||||
- Export/Import Save Files Online/Offline
|
- Export/Import Save Files Online/Offline
|
||||||
|
|
||||||
- Consider controls for fine-tuning music and how they sound during events.
|
|
||||||
|
|
||||||
- Lock up unimplemented classes.
|
- Lock up unimplemented classes.
|
||||||
- Don't enable all stage plates normally.
|
- Don't enable all stage plates normally.
|
||||||
|
|
||||||
|
A "Debug" version of the game that simply outputs all std::cout to a file as well (debug.log).
|
||||||
ERR messages become just output messages in release build and won't crash the game.
|
ERR messages become just output messages in release build and won't crash the game.
|
||||||
|
|
||||||
- Hide mouse cursor during controller play. Reveal it again during mouse play.
|
- Hide mouse cursor during controller play. Reveal it again during mouse play.
|
||||||
|
- Resource Packs
|
||||||
|
|
||||||
|
- Getting hurt has additional effects.
|
||||||
|
|
||||||
|
|
||||||
mainMenuWindow->SetupKeyboardNavigation(
|
mainMenuWindow->SetupKeyboardNavigation(
|
||||||
|
|||||||
@ -37,9 +37,9 @@ All rights reserved.
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
#pragma once
|
#pragma once
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 1
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 6037
|
#define VERSION_BUILD 6071
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Interface
|
Interface
|
||||||
{
|
{
|
||||||
# In pixels/sec
|
# In pixels/sec
|
||||||
AnalogScrollSpeed = 120
|
AnalogScrollSpeed = 220
|
||||||
|
|
||||||
# The size of each side of the 9-patch menu sprite.
|
# The size of each side of the 9-patch menu sprite.
|
||||||
9PatchSize = 24,24
|
9PatchSize = 24,24
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user