Separate GetTextSize and GetWrappedTextSize functions for clarity. Fix sizing comparisons for wrapping text. Fixed issue with menu destinations not properly being assigned on certain buttons.

pull/28/head
sigonasr2 11 months ago
parent d29f7d47bd
commit a26d86d0b0
  1. 4
      Crawler/InventoryWindow.cpp
  2. 6
      Crawler/MenuComponent.cpp
  3. 12
      Crawler/MenuComponent.h
  4. 2
      Crawler/MenuItemButton.h
  5. 2
      Crawler/MenuItemItemButton.h
  6. 9
      Crawler/MenuLabel.h
  7. 4
      Crawler/MerchantWindow.cpp
  8. 1
      Crawler/PlayerMoneyLabel.h
  9. 2
      Crawler/Version.h
  10. 4
      Crawler/olcPGEX_ViewPort.h
  11. 93
      Crawler/olcPixelGameEngine.h

@ -125,11 +125,11 @@ void Menu::InitializeInventoryWindow(){
#pragma endregion
#pragma region Money Display
vf2d moneyIconPos={224+inventoryDescriptionWidth-24,28+inventoryWindow->size.y-44+8};
vf2d moneyIconPos={224+inventoryDescriptionWidth-24,28+inventoryWindow->size.y-44+6};
auto moneyIcon=inventoryWindow->ADD("Money Icon",MenuIconButton)({moneyIconPos,{24,24}},GFX["money.png"].Decal(),DO_NOTHING,IconButtonAttr::NOT_SELECTABLE|IconButtonAttr::NO_OUTLINE|IconButtonAttr::NO_BACKGROUND)END;
std::string moneyText=std::to_string(game->GetPlayer()->GetMoney());
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*2;
auto moneyDisplay=inventoryWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,0},moneyTextSize},2,SHADOW|LEFT_ALIGN)END;
auto moneyDisplay=inventoryWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,SHADOW|LEFT_ALIGN)END;
moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay);
#pragma endregion

@ -119,15 +119,15 @@ void MenuComponent::DrawDecal(ViewPort&window,bool focused){
}
if(showDefaultLabel){
vf2d adjustedScale=labelScaling;
vi2d labelTextSize=game->GetTextSizeProp(label,rect.size.x);
vi2d labelTextSize=vf2d(game->GetTextSizeProp(label))*adjustedScale;
if(fitToLabel){
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
float sizeRatio=((vf2d(labelTextSize)*adjustedScale).x)/(rect.size.x-2);
if(sizeRatio>1){
adjustedScale.x/=sizeRatio;
}
}
window.DrawStringPropDecal(rect.pos+V(A::DRAW_OFFSET)+rect.size/2-vf2d(labelTextSize)/2.f*adjustedScale,label,WHITE,adjustedScale,rect.size.x);
window.DrawStringPropDecal(rect.pos+V(A::DRAW_OFFSET)+rect.size/2-vf2d(labelTextSize)/2.f,label,WHITE,adjustedScale);
}
if(selected){
switch(selectionType){

@ -47,12 +47,12 @@ enum class ButtonAttr{
};
enum class ComponentAttr{
NONE= 0b00000,
LEFT_ALIGN= 0b00001, //Labels are centered by default.
SHADOW= 0b00010, //Adds shadows to the label text.
OUTLINE= 0b00100, //Adds an outline around the component.
BACKGROUND= 0b01000, //Renders the background of the menu theme for this component.
FIT_TO_LABEL= 0b10000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
NONE= 0b000000,
LEFT_ALIGN= 0b000001, //Labels are centered by default.
SHADOW= 0b000010, //Adds shadows to the label text.
OUTLINE= 0b000100, //Adds an outline around the component.
BACKGROUND= 0b001000, //Renders the background of the menu theme for this component.
FIT_TO_LABEL= 0b010000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
};
enum class SelectionType{

@ -141,7 +141,7 @@ protected:
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
vf2d drawPos=rect.pos+rect.size-textSize;
if(itemQuantity!=INFINITE){
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x);
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale);
}
}
}

@ -140,7 +140,7 @@ protected:
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
vf2d drawPos=rect.pos+rect.size-textSize;
if(itemRef.get().Amt()!=INFINITE){
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x);
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale);
}
}
}

@ -67,24 +67,25 @@ protected:
inline virtual void DrawDecal(ViewPort&window,bool focused)override{
MenuComponent::DrawDecal(window,focused);
vf2d adjustedScale={scale,scale};
vf2d labelTextSize=game->GetTextSizeProp(label,rect.size.x);
vf2d labelTextSize=vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale.x));
if(fitToLabel){
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
if(sizeRatio>1){
adjustedScale.x/=sizeRatio;
}
labelTextSize=vf2d(game->GetTextSizeProp(label)*adjustedScale);
}
vf2d drawPos=rect.middle()-vf2d{labelTextSize}*float(adjustedScale.x)/2; //Assume centered.
vf2d drawPos=rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
if(!centered){
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
}
if(shadow){
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,rect.size.x);
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
}else{
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,rect.size.x);
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
}
}
};

@ -103,11 +103,11 @@ void Menu::InitializeMerchantWindow(){
#pragma endregion
#pragma region Money Display
vf2d moneyIconPos={224+inventoryDescriptionWidth-24,28+merchantWindow->size.y-44+8};
vf2d moneyIconPos={224+inventoryDescriptionWidth-24,28+merchantWindow->size.y-44+6};
auto moneyIcon=merchantWindow->ADD("Money Icon",MenuIconButton)({moneyIconPos,{24,24}},GFX["money.png"].Decal(),DO_NOTHING,IconButtonAttr::NOT_SELECTABLE|IconButtonAttr::NO_OUTLINE|IconButtonAttr::NO_BACKGROUND)END;
std::string moneyText=std::to_string(game->GetPlayer()->GetMoney());
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*2;
auto moneyDisplay=merchantWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,0},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
auto moneyDisplay=merchantWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay);
#pragma endregion

@ -53,6 +53,7 @@ public:
std::string moneyText=std::to_string(newMoney);
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*scale;
rect.pos.x=anchorPointX-moneyTextSize.x;
rect.size=moneyTextSize;
}
inline void SetRightAlignment(bool rightAligned){

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 4334
#define VERSION_BUILD 4372
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -708,7 +708,7 @@ void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
planningMarker.x += 8.0f * scale.x;
if(planningMarker.x>=width){
if(planningMarker.x>width){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
@ -834,7 +834,7 @@ void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view s
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
planningMarker.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
if(planningMarker.x>=width){
if(planningMarker.x>width){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);

@ -1120,8 +1120,10 @@ namespace olc
void DrawShadowString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
void DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
olc::vi2d GetTextSize(std::string_view s,const int width=std::numeric_limits<int>::max());
olc::vi2d GetTextSizeProp(std::string_view s,const int width=std::numeric_limits<int>::max());
olc::vi2d GetTextSize(std::string_view s);
olc::vi2d GetTextSizeProp(std::string_view s);
olc::vi2d GetWrappedTextSize(std::string_view s,const float width=std::numeric_limits<int>::max(),const float scale=1);
olc::vi2d GetWrappedTextSizeProp(std::string_view s,const float width=std::numeric_limits<int>::max(),const float scale=1);
void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
@ -3431,7 +3433,7 @@ namespace olc
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
planningMarker.x += 8.0f * scale.x;
if(planningMarker.x>=width){
if(planningMarker.x>width){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
@ -3536,7 +3538,7 @@ namespace olc
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
planningMarker.x += float(vFontSpacing[c - 32].y) * scale.x;
if(planningMarker.x>=width){
if(planningMarker.x>width){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialDecal(pos + drawingMarker, GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
@ -3764,10 +3766,11 @@ namespace olc
DrawRotatedStringPropDecal(pos, sText,fAngle,center,col,scale);
}
olc::vi2d PixelGameEngine::GetTextSize(std::string_view s,const int width)
olc::vi2d PixelGameEngine::GetWrappedTextSize(std::string_view s,const float width,const float scale)
{
float adjustedWidth=width/scale;
int lettersWidth=0;
int maxWidth=0;
float maxWidth=0;
bool wrappingOccurred=false;
olc::vf2d planningMarker = { 0.0f, 0.0f };
olc::vf2d drawingMarker = { 0.0f, 0.0f };
@ -3786,7 +3789,7 @@ namespace olc
if(wrappingOccurred){
if(c!=' '&&c!='\t'){
wrappingOccurred=false;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
maxWidth=std::max(maxWidth,drawingMarker.x);
}else{
continue;
}
@ -3817,11 +3820,11 @@ namespace olc
else
{
planningMarker.x += 8.0f;
if(planningMarker.x>=width){
if(planningMarker.x>adjustedWidth){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
drawingMarker.x+=lettersWidth;
lettersWidth=0;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
maxWidth=std::max(maxWidth,drawingMarker.x);
}
planningMarker.x = 0; planningMarker.y += 8.0f;
drawingMarker=planningMarker;
@ -3832,8 +3835,33 @@ namespace olc
}
}
drawingMarker.x += lettersWidth;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
return {maxWidth,int(planningMarker.y+8)};
return vi2d(vf2d{maxWidth,planningMarker.y+8}*scale);
}
olc::vi2d PixelGameEngine::GetTextSize(std::string_view s)
{
olc::vi2d size = { 0,1 };
olc::vi2d pos = { 0,1 };
for (int skip=0;auto c : s)
{
if(skip){
skip--;
continue;
}
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
if (c == '\n') { pos.y++; pos.x = 0; }
else if (c == '\t') { pos.x += nTabSizeInSpaces; }
else if(c<0)continue;
else if (c=='#')
{
skip=6;
continue;
}
else pos.x++;
size.x = std::max(size.x, pos.x);
size.y = std::max(size.y, pos.y);
}
return size * 8;
}
void PixelGameEngine::DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale)
@ -3925,10 +3953,39 @@ namespace olc
SetPixelMode(m);
}
olc::vi2d PixelGameEngine::GetTextSizeProp(std::string_view s,const int width)
olc::vi2d PixelGameEngine::GetTextSizeProp(std::string_view s)
{
olc::vi2d size = { 0,1 };
olc::vi2d pos = { 0,1 };
for (int skip=0;auto c : s)
{
if(skip){
skip--;
continue;
}
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
if (c == '\n') { pos.y += 1; pos.x = 0; }
else if (c == '\t') { pos.x += nTabSizeInSpaces * 8; }
else if(c<0)continue;
else if (c=='#')
{
skip=6;
continue;
}
else pos.x += vFontSpacing[c - 32].y;
size.x = std::max(size.x, pos.x);
size.y = std::max(size.y, pos.y);
}
size.y *= 8;
return size;
}
olc::vi2d PixelGameEngine::GetWrappedTextSizeProp(std::string_view s,const float width,const float scale)
{
float adjustedWidth=width/scale;
int lettersWidth=0;
int maxWidth=0;
float maxWidth=0;
bool wrappingOccurred=false;
olc::vf2d planningMarker = { 0.0f, 0.0f };
olc::vf2d drawingMarker = { 0.0f, 0.0f };
@ -3943,7 +4000,7 @@ namespace olc
drawingMarker.x+=lettersWidth;
lettersWidth=0;
wrappingOccurred=false;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
maxWidth=std::max(maxWidth,drawingMarker.x);
}
if(wrappingOccurred){
if(c!=' '&&c!='\t'){
@ -3978,11 +4035,11 @@ namespace olc
else
{
planningMarker.x += vFontSpacing[c-32].y;
if(planningMarker.x>=width){
if(planningMarker.x>adjustedWidth){
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
drawingMarker.x+=lettersWidth;
lettersWidth=0;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
maxWidth=std::max(maxWidth,drawingMarker.x);
}
planningMarker.x = 0; planningMarker.y += 8.0f;
drawingMarker=planningMarker;
@ -3993,8 +4050,8 @@ namespace olc
}
}
drawingMarker.x += lettersWidth;
maxWidth=std::max(maxWidth,int(drawingMarker.x));
return {maxWidth,int(planningMarker.y+8)};
maxWidth=std::max(maxWidth,drawingMarker.x);
return vi2d(vf2d{maxWidth,planningMarker.y+8}*scale);
}
void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale)

Loading…
Cancel
Save