Textbox hovering controlling fixed.

CorrectiveAction
sigonasr2 1 year ago
parent 949a1fe9f3
commit 03cd07f6b8
  1. 82
      olcCodeJam2023Entry/Textbox.cpp
  2. 32
      olcCodeJam2023Entry/Textbox.h
  3. 6
      olcCodeJam2023Entry/Unit.cpp
  4. 109
      olcCodeJam2023Entry/VirusAttack.cpp
  5. 3
      olcCodeJam2023Entry/VirusAttack.h
  6. 2
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
  7. 6
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
  8. 15
      olcCodeJam2023Entry/olcPGEX_QuickGUI.h

@ -0,0 +1,82 @@
#include "Textbox.h"
#include "olcUTIL_Geometry2D.h"
Textbox::Textbox(){};
void Textbox::Initialize(std::string text,vf2d pos,std::string headerText,vf2d maxSize,std::vector<Memory>resourceCost,float letterDisplayDelay)
{
if(GetCurrentString()!=text){ //Make sure this is actually a new textbox
SetDefaults();
this->text=text;
this->headerText=headerText;
this->maxSize=maxSize;
this->resourceCost=resourceCost;
this->letterDisplayDelay=letterDisplayDelay;
visible=true;
}
}
void Textbox::SetDefaults(){
lastLetterTime=0;
textboxMarker=-1;
lastWordMarker=-1;
lastWord="";
displayText="";
text="";
}
void Textbox::Update(PixelGameEngine*pge){
lastLetterTime-=pge->GetElapsedTime();
if(lastLetterTime<=0){
if(textboxMarker<int(text.length()-1)){
std::string tempText=displayText;
tempText+=text[textboxMarker+1];
if(pge->GetTextSizeProp(tempText).x>=maxSize.x){
displayText=displayText.substr(0,lastWordMarker);
displayText+='\n';
displayText+=lastWord;
}
if(text[textboxMarker+1]==' '||text[textboxMarker+1]=='\n'){
lastWord="";
lastWordMarker=textboxMarker+2;
} else {
lastWord+=text[textboxMarker+1];
}
displayText+=text[textboxMarker+1];
textboxMarker++;
}
lastLetterTime=letterDisplayDelay;
}
}
void Textbox::Draw(PixelGameEngine*pge,Resources&resources){
if(visible){
vf2d finalPos=pos;
geom2d::rect<float>boxRect={pos-vf2d{2,2},maxSize+vf2d{4,4}};
pge->FillRectDecal(pos-vf2d{2,2},maxSize+vf2d{4,4},VERY_DARK_GREEN);
pge->DrawRectDecal(pos-vf2d{1,1},maxSize+vf2d{3,3},WHITE);
pge->DrawShadowStringPropDecal(pos+vf2d{1,1},displayText,{220,220,220});
}
}
void Textbox::UpdatePosition(vf2d newPos){
pos=newPos;
}
std::string&Textbox::GetCurrentString(){
return text;
}
void Textbox::SetVisible(bool visible){
this->visible=visible;
if(!visible){
SetDefaults();
}
}
void Textbox::UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources){
UpdatePosition(pos);
Update(pge);
Draw(pge,resources);
}

@ -0,0 +1,32 @@
#pragma once
#include "olcPixelGameEngine.h"
#include "Unit.h"
#include "olcPGEX_TransformedView.h"
#include "Resources.h"
class Textbox{
std::string headerText=""; //If a textbox has a header, it displays at the top in a special color.
std::string text="";
std::string displayText="";
vf2d pos={};
vf2d maxSize={};
float lastLetterTime=0;
float letterDisplayDelay=0.01;
int textboxMarker=-1;
int lastWordMarker=-1;
std::string lastWord="";
std::vector<Memory> resourceCost; //If resource cost is greater than 0, shows them.
bool visible=true;
public:
Textbox();
void Initialize(std::string text,vf2d pos,std::string headerText="",vf2d maxSize={120,64},std::vector<Memory>resourceCost={},float letterDisplayDelay=0.01);
void UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources);
std::string&GetCurrentString();
void SetVisible(bool visible);
private:
void Update(PixelGameEngine*pge);
void UpdatePosition(vf2d newPos);
void Draw(PixelGameEngine*pge,Resources&resources);
void SetDefaults();
};

@ -27,7 +27,7 @@ void BasicUnit2::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnit
}
std::string LeftShifter::unitName="Left Shifter";
std::string LeftShifter::unitDescription="Memory Shifts target memory 1 bit to the left";
std::string LeftShifter::unitDescription="Memory Shifts target memory 1 bit to the left.";
std::vector<Memory> LeftShifter::resourceCost={{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1},{HEALTH,4}};
LeftShifter::LeftShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,LeftShifter::resourceCost,pos,12,*IMAGES[LEFT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){}
@ -37,7 +37,7 @@ void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUni
}
std::string RightShifter::unitName="Right Shifter";
std::string RightShifter::unitDescription="Memory Shifts target memory 1 bit to the right";
std::string RightShifter::unitDescription="Memory Shifts target memory 1 bit to the right.";
std::vector<Memory> RightShifter::resourceCost={{HEALTH,4},{RANGE,2},{ATKSPD,2},{MOVESPD,3},{PROCEDURE,1}};
RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,RightShifter::resourceCost,pos,12,*IMAGES[RIGHT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){}
@ -47,7 +47,7 @@ void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUn
}
std::string BitRestorer::unitName="Bit Restorer";
std::string BitRestorer::unitDescription="Randomly restores 1 missing bit to a target";
std::string BitRestorer::unitDescription="Randomly restores 1 missing bit to a target.";
std::vector<Memory> BitRestorer::resourceCost={{PROCEDURE,6},{RANGE,1},{ATKSPD,1},{MOVESPD,1},{HEALTH,2}};
BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit(pge,BitRestorer::resourceCost,pos,12,*IMAGES[BIT_RESTORER],CONSTANT::HEALER_TARGET_COL,CONSTANT::HEALER_ATTACK_COL,friendly,moveable,true,false){}

@ -58,6 +58,10 @@ bool VirusAttack::OnUserCreate(){
InitializeImages();
unitCreationBox.Initialize("Hello world, this is a test of the textbox system.\nMaybe even with some newline characters snuck in there.",
{});
unitCreationBox.SetVisible(false);
IMAGES[MINIMAP_OUTLINE]=std::make_unique<Renderable>();
IMAGES[MINIMAP_OUTLINE]->Create(64,64);
@ -122,77 +126,50 @@ void VirusAttack::InitializeSounds(){
}
bool VirusAttack::UnitCreationClickHandled(){
if(leftShifterButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,LeftShifter::resourceCost)){
std::unique_ptr<LeftShifter>buildUnit=std::make_unique<LeftShifter>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,LeftShifter::resourceCost);
}
}
return true;
}
if(rightShifterButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,RightShifter::resourceCost)){
std::unique_ptr<RightShifter>buildUnit=std::make_unique<RightShifter>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,RightShifter::resourceCost);
}
}
return true;
}
if(bitRestorerButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,BitRestorer::resourceCost)){
std::unique_ptr<BitRestorer>buildUnit=std::make_unique<BitRestorer>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,BitRestorer::resourceCost);
}
}
return true;
}
if(memorySwapperButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,MemorySwapper::resourceCost)){
std::unique_ptr<MemorySwapper>buildUnit=std::make_unique<MemorySwapper>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,MemorySwapper::resourceCost);
}
}
return true;
}
if(corrupterButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,Corrupter::resourceCost)){
std::unique_ptr<Corrupter>buildUnit=std::make_unique<Corrupter>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,Corrupter::resourceCost);
}
}
return true;
}
if(platformButton->bPressed){
for(auto&u:units){
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,MemoryAllocator::resourceCost)){
std::unique_ptr<MemoryAllocator>buildUnit=std::make_unique<MemoryAllocator>(this,u->GetPos(),IMAGES,u->IsFriendly());
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit));
ExpendResources(player_resources,MemoryAllocator::resourceCost);
}
#define CheckClick(UnitClass,Button) \
if(Button->bPressed){ \
for(auto&u:units){ \
if(u->IsSelected()&&u->IsAllocator()&&CanAfford(player_resources,UnitClass::resourceCost)) { \
std::unique_ptr<UnitClass>buildUnit=std::make_unique<UnitClass>(this,u->GetPos(),IMAGES,u->IsFriendly()); \
u->SetBuildUnit(CONSTANT::UNIT_BUILD_TIME,std::move(buildUnit)); \
ExpendResources(player_resources,UnitClass::resourceCost); \
} \
} \
return true; \
}
return true;
}
CheckClick(LeftShifter,leftShifterButton)
CheckClick(RightShifter,rightShifterButton)
CheckClick(BitRestorer,bitRestorerButton)
CheckClick(MemorySwapper,memorySwapperButton)
CheckClick(BitRestorer,bitRestorerButton)
CheckClick(Corrupter,corrupterButton)
CheckClick(MemoryAllocator,platformButton)
return false;
};
void VirusAttack::UpdateUnitCreationListGUI(bool allocatorSelected){
unitCreationList.DisplayAllControls(allocatorSelected);
leftShifterButton->Enable(CanAfford(player_resources,LeftShifter::resourceCost));
rightShifterButton->Enable(CanAfford(player_resources,RightShifter::resourceCost));
bitRestorerButton->Enable(CanAfford(player_resources,BitRestorer::resourceCost));
memorySwapperButton->Enable(CanAfford(player_resources,MemorySwapper::resourceCost));
corrupterButton->Enable(CanAfford(player_resources,Corrupter::resourceCost));
platformButton->Enable(CanAfford(player_resources,MemoryAllocator::resourceCost));
#define EnableAndHoverCheck(UnitClass,Button) \
Button->Enable(CanAfford(player_resources,UnitClass::resourceCost)); \
if (Button->bHover) { \
unitCreationBox.Initialize(UnitClass::unitDescription, GetMousePos(), UnitClass::unitName); \
hovering=true; \
}
bool hovering=false;
EnableAndHoverCheck(LeftShifter,leftShifterButton)
EnableAndHoverCheck(RightShifter,rightShifterButton)
EnableAndHoverCheck(BitRestorer,bitRestorerButton)
EnableAndHoverCheck(MemorySwapper,memorySwapperButton)
EnableAndHoverCheck(BitRestorer,bitRestorerButton)
EnableAndHoverCheck(Corrupter,corrupterButton)
EnableAndHoverCheck(MemoryAllocator,platformButton)
if(!hovering){
unitCreationBox.SetVisible(false);
}
unitCreationList.Update(this);
}
@ -556,6 +533,8 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
DrawMinimap();
unitCreationBox.UpdateAndDraw(GetMousePos(),this,player_resources);
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length();
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length();

@ -11,6 +11,7 @@
#include "DebuffIcon.h"
#include "CollectionPoint.h"
#include "Resources.h"
#include "Textbox.h"
struct Letter{
vf2d pos;
@ -37,6 +38,8 @@ private:
TileTransformedView game;
Textbox unitCreationBox;
QuickGUI::Manager unitCreationList;
QuickGUI::ImageButton*leftShifterButton;
QuickGUI::ImageButton*rightShifterButton;

@ -159,6 +159,7 @@
<ClInclude Include="resource1.h" />
<ClInclude Include="Resources.h" />
<ClInclude Include="Sound.h" />
<ClInclude Include="Textbox.h" />
<ClInclude Include="TileManager.h" />
<ClInclude Include="Unit.h" />
<ClInclude Include="util.h" />
@ -169,6 +170,7 @@
<ClCompile Include="Constant.cpp" />
<ClCompile Include="DeathAnimations.cpp" />
<ClCompile Include="DebuffIcon.cpp" />
<ClCompile Include="Textbox.cpp" />
<ClCompile Include="TileManager.cpp" />
<ClCompile Include="Unit.cpp" />
<ClCompile Include="util.cpp" />

@ -90,6 +90,9 @@
<ClInclude Include="Resources.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Textbox.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="VirusAttack.cpp">
@ -116,6 +119,9 @@
<ClCompile Include="CollectionPoint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Textbox.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="olcCodeJam2023Entry.rc">

@ -80,6 +80,7 @@
namespace olc::QuickGUI
{
enum class State { Disabled, Normal, Hover, Click };
class Manager;
// Virtual base class for all controls
@ -101,6 +102,7 @@ namespace olc::QuickGUI
bool bHeld = false;
// True on single frame control ceases being manipulated
bool bReleased = false;
bool bHover = false;
public:
// Updates the controls behvaiour
@ -111,6 +113,7 @@ namespace olc::QuickGUI
virtual void DrawDecal(TileTransformedView&pge) = 0;
virtual void Update(PixelGameEngine*pge);
virtual void DrawDecal(PixelGameEngine*pge);
State m_state = State::Normal;
protected:
// Controls are related to a manager, where the theme resides
@ -122,7 +125,6 @@ namespace olc::QuickGUI
// Normal - interactive and operational
// Hover - currently under the users mouse focus
// Click - user is interacting with the control
enum class State { Disabled, Normal, Hover, Click } m_state = State::Normal;
// To add a "swish" to things, controls can fade between states
float m_fTransition = 0.0;
@ -586,6 +588,7 @@ namespace olc::QuickGUI
if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
{
bHover = true;
// Released inside box does nothing to me, but i may have
// to finish off the neighbours... oo err
bPressed = pge.GetPGE()->GetMouse(olc::Mouse::LEFT).bPressed;
@ -609,6 +612,7 @@ namespace olc::QuickGUI
}
else
{
bHover = false;
// Released outside box
bPressed = pge.GetPGE()->GetMouse(olc::Mouse::LEFT).bPressed;
bReleased = pge.GetPGE()->GetMouse(olc::Mouse::LEFT).bReleased;
@ -706,6 +710,7 @@ namespace olc::QuickGUI
if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
{
bHover = true;
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
m_state = State::Hover;
@ -719,6 +724,7 @@ namespace olc::QuickGUI
}
else
{
bHover = false;
m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
m_state = State::Normal;
}
@ -748,6 +754,7 @@ namespace olc::QuickGUI
if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
{
bHover = true;
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
m_state = State::Hover;
@ -761,6 +768,7 @@ namespace olc::QuickGUI
}
else
{
bHover = false;
m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
m_state = State::Normal;
}
@ -997,6 +1005,7 @@ namespace olc::QuickGUI
olc::vf2d vSliderPos = vPosMin + (vPosMax - vPosMin) * ((fValue - fMin) / (fMax - fMin));
if ((vMouse - vSliderPos).mag2() <= int32_t(m_manager.fGrabRad) * int32_t(m_manager.fGrabRad))
{
bHover = true;
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
m_state = State::Hover;
if (pge.GetPGE()->GetMouse(olc::Mouse::LEFT).bPressed)
@ -1005,8 +1014,10 @@ namespace olc::QuickGUI
bPressed = true;
}
}
else
else{
bHover = false;
m_state = State::Normal;
}
}
if (pge.GetPGE()->GetMouse(olc::Mouse::LEFT).bReleased)

Loading…
Cancel
Save