Add in new and edit buttons. Add delete functionality.

master
sigonasr2 1 year ago
parent 4c5781d0c9
commit 121845a4af
  1. BIN
      TiledCollisionEditor/EditButton.png
  2. 178
      TiledCollisionEditor/main.cpp
  3. BIN
      TiledCollisionEditor/newCollisionButton.png
  4. 241
      TiledCollisionEditor/olcPGEX_QuickGUI.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

@ -6,6 +6,7 @@
using namespace olc; using namespace olc;
using namespace olc::utils; using namespace olc::utils;
using namespace QuickGUI;
const std::string TILESET_DIR="./Tiles/"; const std::string TILESET_DIR="./Tiles/";
@ -23,6 +24,8 @@ class TiledCollisionEditor : public olc::PixelGameEngine
vf2d upperLeftDragOffset{}; vf2d upperLeftDragOffset{};
Renderable circle; Renderable circle;
Renderable createNewButtonImg;
Renderable editButtonImg;
TransformedView view; TransformedView view;
@ -34,6 +37,11 @@ public:
Renderable rollingCounter; Renderable rollingCounter;
Manager gui;
ImageCheckBox*createNewButton;
ImageCheckBox*editButton;
public: public:
bool OnUserCreate() override bool OnUserCreate() override
{ {
@ -46,6 +54,9 @@ public:
SetDrawTarget(nullptr); SetDrawTarget(nullptr);
circle.Decal()->Update(); circle.Decal()->Update();
createNewButtonImg.Load("newCollisionButton.png");
editButtonImg.Load("EditButton.png");
std::string tilesetFilename=TILESET_DIR+"Basic Tileset.tsx"; std::string tilesetFilename=TILESET_DIR+"Basic Tileset.tsx";
Tileset&tileset=tilesets[tilesetFilename]=TSXParser{tilesetFilename}.GetData(); Tileset&tileset=tilesets[tilesetFilename]=TSXParser{tilesetFilename}.GetData();
@ -55,6 +66,11 @@ public:
tilesetImg.Load(TILESET_DIR+tileset.filename); tilesetImg.Load(TILESET_DIR+tileset.filename);
if(tilesets.size()==1)activeTileset=tilesetFilename; if(tilesets.size()==1)activeTileset=tilesetFilename;
createNewButton=new ImageCheckBox{gui,createNewButtonImg,false,vf2d{4.f,ScreenHeight()-36.f},{32.f,32.f},{4,1},{32,32}};
createNewButton->hotkey=Q;
editButton=new ImageCheckBox{gui,editButtonImg,true,vf2d{40.f,ScreenHeight()-36.f},{32.f,32.f},{4,4},{32,32}};
editButton->hotkey=E;
return true; return true;
} }
@ -65,42 +81,9 @@ public:
float currentHealth=0; float currentHealth=0;
float targetHealth=60; float targetHealth=60;
bool OnUserUpdate(float fElapsedTime) override void Update(){
{
Clear(VERY_DARK_BLUE);
view.HandlePanAndZoom();
const Tileset&tileset=tilesets[activeTileset]; const Tileset&tileset=tilesets[activeTileset];
view.DrawDecal({0,0},images[activeTileset].Decal());
for(int y=0;y<tileset.tilecount/tileset.columns;y++){
for(int x=0;x<tileset.columns;x++){
view.DrawRectDecal(vf2d{float(x),float(y)}*tileset.tilewidth,vf2d{float(tileset.tilewidth),float(tileset.tileheight)},GREY);
}
}
if(editingQuad==nullptr){
std::string selectedObj="";
}
for(auto&[objName,obj]:tileset.objects){
view.DrawLineDecal(obj.bounds.pos,obj.bounds.pos+vf2d{0.f,float(obj.bounds.size.y)},YELLOW);
view.DrawLineDecal(obj.bounds.pos,obj.bounds.pos+vf2d{float(obj.bounds.size.x),0.f},YELLOW);
view.DrawLineDecal(obj.bounds.pos+obj.bounds.size,obj.bounds.pos+obj.bounds.size+vf2d{0.f,-float(obj.bounds.size.y)},YELLOW);
view.DrawLineDecal(obj.bounds.pos+obj.bounds.size,obj.bounds.pos+obj.bounds.size+vf2d{-float(obj.bounds.size.x),0.f},YELLOW);
vi2d nameTextSize=GetTextSizeProp(objName)*0.25f;
view.GradientFillRectDecal(obj.bounds.pos,nameTextSize+vf2d{2,2},RED,{255,0,0,64},{255,0,0,64},RED);
view.DrawStringPropDecal(obj.bounds.pos+vf2d{1.25f,1.25f},objName,BLACK,vf2d{0.25f,0.25f});
view.DrawStringPropDecal(obj.bounds.pos+vf2d{1,1},objName,WHITE,vf2d{0.25f,0.25f});
if(geom2d::contains(obj.bounds,view.ScreenToWorld(GetMousePos()))){
selectedObj=objName;
}
}
if(selectedObj.length()>0){ if(selectedObj.length()>0){
for(int y=0;y<tileset.tilecount/tileset.columns;y++){ for(int y=0;y<tileset.tilecount/tileset.columns;y++){
for(int x=0;x<tileset.columns;x++){ for(int x=0;x<tileset.columns;x++){
@ -140,7 +123,7 @@ public:
pointInd++; pointInd++;
} }
} }
if(editButton->bChecked){
if(GetMouse(Mouse::LEFT).bPressed){ if(GetMouse(Mouse::LEFT).bPressed){
#pragma region Select a point on a collision quad. #pragma region Select a point on a collision quad.
for(const Quadrilateral&quad:obj.collisionTiles){ for(const Quadrilateral&quad:obj.collisionTiles){
@ -149,6 +132,7 @@ public:
if(GetMouse(Mouse::LEFT).bPressed){ if(GetMouse(Mouse::LEFT).bPressed){
editingPoint=pointInd; editingPoint=pointInd;
editingQuad=const_cast<Quadrilateral*>(&quad); editingQuad=const_cast<Quadrilateral*>(&quad);
originalQuad=quad;
} }
goto exitCollisionCheck; goto exitCollisionCheck;
} }
@ -175,8 +159,20 @@ public:
if(EditingQuad&&!dragging){ if(EditingQuad&&!dragging){
(*editingQuad)[editingPoint]=GetSnapPoint(); (*editingQuad)[editingPoint]=GetSnapPoint();
editingPoint++; editingPoint++;
}
}
if(GetMouse(Mouse::RIGHT).bPressed||GetKey(ESCAPE).bPressed){
if(EditingQuad||dragTranslate){
editingPoint=4;
dragging=false;
*editingQuad=originalQuad;
editingQuad=nullptr;
dragTranslate=false;
}
}
}else{ }else{
if(obj.collisionTiles.size()==0){ if(GetMouse(Mouse::LEFT).bPressed){
Quadrilateral newQuad{GetSnapPoint()}; Quadrilateral newQuad{GetSnapPoint()};
tilesets[activeTileset].objects[selectedObj].collisionTiles.push_back(newQuad); tilesets[activeTileset].objects[selectedObj].collisionTiles.push_back(newQuad);
dragging=true; dragging=true;
@ -184,6 +180,26 @@ public:
originalQuad=*editingQuad; originalQuad=*editingQuad;
} }
} }
if(GetMouse(Mouse::RIGHT).bPressed&&!EditingQuad&&!dragTranslate){
std::vector<Quadrilateral*>quadsToBeRemoved;
for(const Quadrilateral&quad:obj.collisionTiles){
std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{quad[0],quad[1],quad[2]},
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
};
for(geom2d::triangle<float>&tri:collisionTris){
if(geom2d::contains(tri,view.ScreenToWorld(GetMousePos()))){
//Delete this quad, the mouse is overlapping it!
quadsToBeRemoved.push_back(const_cast<Quadrilateral*>(&quad));
break;
}
}
}
for(Quadrilateral*quad:quadsToBeRemoved){
std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==quad;});
}
} }
if(GetMouse(Mouse::LEFT).bReleased){ if(GetMouse(Mouse::LEFT).bReleased){
@ -201,23 +217,72 @@ public:
} }
dragTranslate=false; dragTranslate=false;
} }
}
}
if(GetMouse(Mouse::RIGHT).bPressed||GetKey(ESCAPE).bPressed){ bool OnUserUpdate(float fElapsedTime) override
if(EditingQuad){ {
editingPoint=4; Clear(VERY_DARK_BLUE);
dragging=false;
*editingQuad=originalQuad; view.HandlePanAndZoom();
editingQuad=nullptr;
const float CAMERA_MOVESPD = 150.f;
if(GetKey(W).bHeld)view.MoveWorldOffset(vf2d{0.f,-CAMERA_MOVESPD}*fElapsedTime/view.GetWorldScale());
if(GetKey(S).bHeld)view.MoveWorldOffset(vf2d{0.f,CAMERA_MOVESPD}*fElapsedTime/view.GetWorldScale());
if(GetKey(A).bHeld)view.MoveWorldOffset(vf2d{-CAMERA_MOVESPD,0.f}*fElapsedTime/view.GetWorldScale());
if(GetKey(D).bHeld)view.MoveWorldOffset(vf2d{CAMERA_MOVESPD,0.f}*fElapsedTime/view.GetWorldScale());
const Tileset&tileset=tilesets[activeTileset];
view.DrawDecal({0,0},images[activeTileset].Decal());
for(int y=0;y<tileset.tilecount/tileset.columns;y++){
for(int x=0;x<tileset.columns;x++){
view.DrawRectDecal(vf2d{float(x),float(y)}*tileset.tilewidth,vf2d{float(tileset.tilewidth),float(tileset.tileheight)},GREY);
}
} }
if(editingQuad==nullptr){
std::string selectedObj="";
} }
if(createNewButton->bPressed)editButton->bChecked=false;
if(editButton->bPressed)createNewButton->bChecked=false;
if(GetMouseY()<ScreenHeight()-36||GetMouseX()>72){
Update();
}
//Font test.
/*DrawStringDecal({0,0},"the quick brown fox jumps over the lazy dog 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f});
DrawStringDecal({0,18},"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f});
DrawStringPropDecal({0,36},"the quick brown fox jumps over the lazy dog 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f});
DrawStringPropDecal({0,54},"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f});
*/
if(selectedObj.length()>0){
const TilesetObject&obj=tileset.objects.at(selectedObj);
Quadrilateral*highlightedQuad=nullptr;
for(const Quadrilateral&quad:obj.collisionTiles){
std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{quad[0],quad[1],quad[2]},
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
};
for(geom2d::triangle<float>&tri:collisionTris){
if(geom2d::contains(tri,view.ScreenToWorld(GetMousePos()))){
highlightedQuad=const_cast<Quadrilateral*>(&quad);
goto renderQuads;
}
}
}
renderQuads:
for(const Quadrilateral&quad:obj.collisionTiles){ for(const Quadrilateral&quad:obj.collisionTiles){
std::vector<vf2d>points; std::vector<vf2d>points;
std::vector<vf2d>uvs; std::vector<vf2d>uvs;
std::vector<Pixel>cols; std::vector<Pixel>cols;
points.assign(quad.begin(),quad.end()); points.assign(quad.begin(),quad.end());
uvs.assign(4,{0.f,0.f}); uvs.assign(4,{0.f,0.f});
cols.assign(4,{255,40,40,128}); cols.assign(4,(!GetMouse(Mouse::LEFT).bHeld&&highlightedQuad==&quad)?Pixel{255,20,20,150}:Pixel{255,40,40,128});
view.DrawPolygonDecal(nullptr,points,uvs,cols); view.DrawPolygonDecal(nullptr,points,uvs,cols);
for(bool highlighted=false;const vf2d&point:quad){ for(bool highlighted=false;const vf2d&point:quad){
@ -231,12 +296,27 @@ public:
} }
} }
//Font test. for(auto&[objName,obj]:tileset.objects){
/*DrawStringDecal({0,0},"the quick brown fox jumps over the lazy dog 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f}); view.DrawLineDecal(obj.bounds.pos,obj.bounds.pos+vf2d{0.f,float(obj.bounds.size.y)},YELLOW);
DrawStringDecal({0,18},"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f}); view.DrawLineDecal(obj.bounds.pos,obj.bounds.pos+vf2d{float(obj.bounds.size.x),0.f},YELLOW);
DrawStringPropDecal({0,36},"the quick brown fox jumps over the lazy dog 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f}); view.DrawLineDecal(obj.bounds.pos+obj.bounds.size,obj.bounds.pos+obj.bounds.size+vf2d{0.f,-float(obj.bounds.size.y)},YELLOW);
DrawStringPropDecal({0,54},"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 1234567890 !@#$%^&*()-=_+[]{}\\;':\",./<>?~`",WHITE,{1.5f,1.5f}); view.DrawLineDecal(obj.bounds.pos+obj.bounds.size,obj.bounds.pos+obj.bounds.size+vf2d{-float(obj.bounds.size.x),0.f},YELLOW);
*/
vi2d nameTextSize=GetTextSizeProp(objName)*0.25f;
view.GradientFillRectDecal(obj.bounds.pos,nameTextSize+vf2d{2,2},RED,{255,0,0,64},{255,0,0,64},RED);
view.DrawStringPropDecal(obj.bounds.pos+vf2d{1.25f,1.25f},objName,BLACK,vf2d{0.25f,0.25f});
view.DrawStringPropDecal(obj.bounds.pos+vf2d{1,1},objName,WHITE,vf2d{0.25f,0.25f});
if(geom2d::contains(obj.bounds,view.ScreenToWorld(GetMousePos()))){
selectedObj=objName;
}
}
gui.Update(this);
gui.DrawDecal(this);
DrawStringDecal(createNewButton->vPos+vf2d{3,0},"Q");
DrawStringDecal(editButton->vPos+vf2d{3,0},"E");
return true; return true;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

@ -1,5 +1,5 @@
/* /*
OneLoneCoder - QuickGUI v1.03 OneLoneCoder - QuickGUI v1.02
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A semi-immediate mode GUI for very simple GUI stuff. A semi-immediate mode GUI for very simple GUI stuff.
Includes: Includes:
@ -15,7 +15,7 @@
License (OLC-3) License (OLC-3)
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
Copyright 2018 - 2024 OneLoneCoder.com Copyright 2018 - 2021 OneLoneCoder.com
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -56,7 +56,7 @@
Author Author
~~~~~~ ~~~~~~
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022, 2023, 2024 David Barr, aka javidx9, <EFBFBD>OneLoneCoder 2019, 2020, 2021, 2022
Changes Changes
~~~~~~~ ~~~~~~~
@ -68,7 +68,6 @@
+ListBox::bSelectionChanged flag, true when list selected item changes +ListBox::bSelectionChanged flag, true when list selected item changes
=Fix - Text box mouse behaviours, mouse release is now meaningless =Fix - Text box mouse behaviours, mouse release is now meaningless
+CheckBox Fix for decal display +CheckBox Fix for decal display
v1.03 =Fix ImageCheckBox
*/ */
@ -101,6 +100,8 @@ namespace olc::QuickGUI
bool bHeld = false; bool bHeld = false;
// True on single frame control ceases being manipulated // True on single frame control ceases being manipulated
bool bReleased = false; bool bReleased = false;
// true on all frames control is being hovered over
bool bHovered = false;
public: public:
// Updates the controls behvaiour // Updates the controls behvaiour
@ -148,12 +149,14 @@ namespace olc::QuickGUI
public: // This managers "Theme" can be set here public: // This managers "Theme" can be set here
// Various element colours // Various element colours
olc::Pixel colNormal = olc::DARK_BLUE; olc::Pixel colNormal = {45, 0, 105};
olc::Pixel colHover = olc::BLUE; olc::Pixel colSelected = {183, 99, 201};
olc::Pixel colClick = olc::CYAN; olc::Pixel colHover = {173, 127, 235};
olc::Pixel colDisable = olc::DARK_GREY; olc::Pixel colClick = {129, 36, 255};
olc::Pixel colBorder = olc::WHITE; olc::Pixel colDisable = {93, 87, 102};
olc::Pixel colText = olc::WHITE; olc::Pixel colBorder = {209, 209, 209};
olc::Pixel colBorderSelected = {63, 35, 84};
olc::Pixel colText = {209, 209, 209};
// Speed to transiton from Normal -> Hover // Speed to transiton from Normal -> Hover
float fHoverSpeedOn = 10.0f; float fHoverSpeedOn = 10.0f;
// Speed to transiton from Hover -> Normal // Speed to transiton from Hover -> Normal
@ -207,16 +210,17 @@ namespace olc::QuickGUI
TextBox(olc::QuickGUI::Manager& manager, // Associate with a Manager TextBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
const std::string& text, // Text to display const std::string& text, // Text to display
const olc::vf2d& pos, // Location of text box top-left const olc::vf2d& pos, // Location of text box top-left
const olc::vf2d& size); // Size of text box const olc::vf2d& size,
const olc::vf2d& fontSize={1,1}); // Size of text box
public: // BaseControl overrides public: // BaseControl overrides
void Update(olc::PixelGameEngine* pge) override; void Update(olc::PixelGameEngine* pge) override;
void Draw(olc::PixelGameEngine* pge) override; void Draw(olc::PixelGameEngine* pge) override;
void DrawDecal(olc::PixelGameEngine* pge) override; void DrawDecal(olc::PixelGameEngine* pge) override;
protected:
bool m_bTextEdit = false; bool m_bTextEdit = false;
protected:
vf2d fontSize;
}; };
// Creates a Button Control - a clickable, labelled rectangle // Creates a Button Control - a clickable, labelled rectangle
@ -226,7 +230,8 @@ namespace olc::QuickGUI
Button(olc::QuickGUI::Manager& manager, // Associate with a Manager Button(olc::QuickGUI::Manager& manager, // Associate with a Manager
const std::string& text, // Text to display const std::string& text, // Text to display
const olc::vf2d& pos, // Location of button top-left const olc::vf2d& pos, // Location of button top-left
const olc::vf2d& size); // Size of button const olc::vf2d& size,
const olc::vf2d& fontScale={1,1}); // Size of button
public: public:
// Position of button // Position of button
@ -235,6 +240,8 @@ namespace olc::QuickGUI
olc::vf2d vSize; olc::vf2d vSize;
// Text displayed on button // Text displayed on button
std::string sText; std::string sText;
olc::vf2d fontScale;
Key hotkey{NONE};
public: // BaseControl overrides public: // BaseControl overrides
void Update(olc::PixelGameEngine* pge) override; void Update(olc::PixelGameEngine* pge) override;
@ -261,16 +268,41 @@ namespace olc::QuickGUI
void DrawDecal(olc::PixelGameEngine* pge) override; void DrawDecal(olc::PixelGameEngine* pge) override;
}; };
class CustomButton : public Button
{
public:
CustomButton(olc::QuickGUI::Manager& manager, // Associate with a Manager
const olc::Renderable &icon, // Text to display
const olc::Renderable &back_icon, // The image that appears behind the button, to be blended.
const olc::vf2d& pos, // Location of button top-left
const olc::vf2d& size,
const olc::vi2d& sprOffset,
const olc::vi2d& sprSize); // Size of button
public:
const olc::Renderable& pIcon;
const olc::Renderable& pBackIcon;
olc::vi2d sprOffset;
olc::vi2d sprSize;
public:
void DrawDecal(olc::PixelGameEngine* pge) override;
};
class ImageButton : public Button class ImageButton : public Button
{ {
public: public:
ImageButton(olc::QuickGUI::Manager& manager, // Associate with a Manager ImageButton(olc::QuickGUI::Manager& manager, // Associate with a Manager
const olc::Renderable &icon, // Text to display const olc::Renderable &icon, // Text to display
const olc::vf2d& pos, // Location of button top-left const olc::vf2d& pos, // Location of button top-left
const olc::vf2d& size); // Size of button const olc::vf2d& size,
const olc::vi2d& sprOffset,
const olc::vi2d& sprSize); // Size of button
public: public:
const olc::Renderable& pIcon; const olc::Renderable& pIcon;
olc::vi2d sprOffset;
olc::vi2d sprSize;
public: public:
void Draw(olc::PixelGameEngine* pge) override; void Draw(olc::PixelGameEngine* pge) override;
@ -284,7 +316,9 @@ namespace olc::QuickGUI
const olc::Renderable& icon, // Text to display const olc::Renderable& icon, // Text to display
const bool check, // Is checked or not? const bool check, // Is checked or not?
const olc::vf2d& pos, // Location of button top-left const olc::vf2d& pos, // Location of button top-left
const olc::vf2d& size); // Size of button const olc::vf2d& size,
const olc::vi2d& sprOffset,
const olc::vi2d& sprSize); // Size of button
public: public:
bool bChecked = false; bool bChecked = false;
@ -333,7 +367,8 @@ namespace olc::QuickGUI
ListBox(olc::QuickGUI::Manager& manager, // Associate with a Manager ListBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
std::vector<std::string>& vList, std::vector<std::string>& vList,
const olc::vf2d& pos, // Location of list top-left const olc::vf2d& pos, // Location of list top-left
const olc::vf2d& size); // Size of list const olc::vf2d& size, // Location of list top-left
const float fontSize=10); // Size of list
// Position of list // Position of list
olc::vf2d vPos; olc::vf2d vPos;
@ -349,6 +384,7 @@ namespace olc::QuickGUI
Manager m_group; Manager m_group;
size_t m_nVisibleItems = 0; size_t m_nVisibleItems = 0;
std::vector<std::string>& m_vList; std::vector<std::string>& m_vList;
float fontSize=10;
public: public:
// Item currently selected // Item currently selected
@ -537,8 +573,8 @@ namespace olc::QuickGUI
#pragma region TextBox #pragma region TextBox
TextBox::TextBox(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size) TextBox::TextBox(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size,const olc::vf2d& fontSize)
: Label(manager, text, pos, size) : Label(manager, text, pos, size),fontSize(fontSize)
{ {
nAlign = Alignment::Left; nAlign = Alignment::Left;
bHasBorder = true; bHasBorder = true;
@ -555,6 +591,12 @@ namespace olc::QuickGUI
olc::vf2d vMouse = pge->GetMousePos(); olc::vf2d vMouse = pge->GetMousePos();
if (m_bTextEdit && !pge->IsTextEntryEnabled()){
//sText = pge->TextEntryGetString();
m_bTextEdit = false;
}
if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x && if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y) vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
{ {
@ -577,7 +619,6 @@ namespace olc::QuickGUI
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld; bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
} }
else else
{ {
@ -586,7 +627,7 @@ namespace olc::QuickGUI
bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased; bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld; bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
if (bPressed && m_bTextEdit) if (bPressed && m_bTextEdit && pge->IsTextEntryEnabled())
{ {
sText = pge->TextEntryGetString(); sText = pge->TextEntryGetString();
pge->TextEntryEnable(false); pge->TextEntryEnable(false);
@ -646,19 +687,19 @@ namespace olc::QuickGUI
{ {
// Draw Cursor // Draw Cursor
int32_t i = pge->TextEntryGetCursor(); int32_t i = pge->TextEntryGetCursor();
olc::vf2d vCursorPos = pge->GetTextSizeProp(sText.substr(0, i)); olc::vf2d vCursorPos = pge->GetTextSizeProp(sText.substr(0, i))*fontSize;
pge->FillRectDecal(olc::vf2d(vPos.x + 2.0f + vCursorPos.x, (vPos.y + (vSize.y - 10.0f) * 0.5f)), { 2, 10 }, m_manager.colText); pge->FillRectDecal(olc::vf2d(vPos.x + 2.0f + vCursorPos.x, (vPos.y + (vSize.y - 10.0f) * 0.5f)), { 2, 10 }, m_manager.colText);
} }
// Draw Text // Draw Text
olc::vf2d vText = pge->GetTextSizeProp(sText); olc::vf2d vText = pge->GetTextSizeProp(sText);
pge->DrawStringPropDecal(olc::vf2d(vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f), sText, m_manager.colText); pge->DrawStringPropDecal(olc::vf2d(vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f)-vf2d{0,1*fontSize.y}, sText, m_manager.colText,fontSize);
} }
#pragma endregion #pragma endregion
#pragma region Button #pragma region Button
Button::Button(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size) Button::Button(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size, const olc::vf2d& fontScale)
: BaseControl(manager) : BaseControl(manager),fontScale(fontScale)
{ {
vPos = pos; vSize = size; sText = text; vPos = pos; vSize = size; sText = text;
} }
@ -676,29 +717,32 @@ namespace olc::QuickGUI
if (m_state != State::Click) if (m_state != State::Click)
{ {
if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x && if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y) vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y
||pge->GetKey(hotkey).bPressed||pge->GetKey(hotkey).bHeld||pge->GetKey(hotkey).bReleased)
{ {
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn; m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
m_state = State::Hover; m_state = State::Hover;
bHovered = true;
bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed; bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed||pge->GetKey(hotkey).bPressed;
if (bPressed) if (bPressed)
{ {
m_state = State::Click; m_state = State::Click;
} }
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld; bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld||pge->GetKey(hotkey).bHeld;
} }
else else
{ {
m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff; m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
m_state = State::Normal; m_state = State::Normal;
bHovered = false;
} }
} }
else else
{ {
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld; bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld||pge->GetKey(hotkey).bHeld;
bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased; bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased||pge->GetKey(hotkey).bReleased;
if (bReleased) m_state = State::Normal; if (bReleased) m_state = State::Normal;
} }
@ -751,36 +795,62 @@ namespace olc::QuickGUI
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colBorder); pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colBorder);
pge->SetDecalMode(olc::DecalMode::NORMAL); pge->SetDecalMode(olc::DecalMode::NORMAL);
olc::vf2d vText = pge->GetTextSizeProp(sText); olc::vf2d vText = pge->GetTextSizeProp(sText)*fontScale;
pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText); pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText,fontScale);
} }
#pragma endregion #pragma endregion
#pragma region CustomButton
CustomButton::CustomButton(olc::QuickGUI::Manager& manager, const olc::Renderable& icon,const olc::Renderable& back_icon, const olc::vf2d& pos, const olc::vf2d& size,const olc::vi2d& sprOffset,const olc::vi2d& sprSize)
: Button(manager, "", pos, size), pIcon(icon), pBackIcon(back_icon), sprOffset(sprOffset), sprSize(sprSize)
{}
#pragma region ImageButton void CustomButton::DrawDecal(olc::PixelGameEngine* pge)
ImageButton::ImageButton(olc::QuickGUI::Manager& manager, const olc::Renderable& icon, const olc::vf2d& pos, const olc::vf2d& size)
: Button(manager, "", pos, size), pIcon(icon)
{ {
if (!bVisible)
return;
switch (m_state)
{
case State::Disabled:
pge->DrawPartialDecal(vPos,pBackIcon.Decal(),sprOffset,sprSize,{1.0,1.0},m_manager.colDisable);
break;
case State::Normal:
case State::Hover:
pge->DrawPartialDecal(vPos,pBackIcon.Decal(),sprOffset,sprSize,{1.0,1.0},olc::PixelLerp(m_manager.colNormal, m_manager.colHover, m_fTransition));
break;
case State::Click:
pge->DrawPartialDecal(vPos,pBackIcon.Decal(),sprOffset,sprSize,{1.0,1.0},m_manager.colClick);
break;
}
pge->DrawPartialDecal(vPos,pIcon.Decal(),sprOffset,sprSize,{1.0,1.0},WHITE);
}
#pragma endregion
#pragma region ImageButton
ImageButton::ImageButton(olc::QuickGUI::Manager& manager, const olc::Renderable& icon, const olc::vf2d& pos, const olc::vf2d& size,const olc::vi2d& sprOffset,const olc::vi2d& sprSize)
: Button(manager, "", pos, size), pIcon(icon), sprOffset(sprOffset), sprSize(sprSize)
{
} }
void ImageButton::Draw(olc::PixelGameEngine* pge) void ImageButton::Draw(olc::PixelGameEngine* pge)
{ {
Button::Draw(pge); Button::Draw(pge);
pge->DrawSprite(vPos + olc::vi2d(4, 4), pIcon.Sprite()); pge->DrawPartialSprite(vPos + olc::vi2d(4, 4), pIcon.Sprite(),sprOffset,sprSize);
} }
void ImageButton::DrawDecal(olc::PixelGameEngine* pge) void ImageButton::DrawDecal(olc::PixelGameEngine* pge)
{ {
Button::DrawDecal(pge); Button::DrawDecal(pge);
pge->DrawDecal(vPos + olc::vi2d(4, 4), pIcon.Decal()); pge->DrawPartialDecal(vPos + olc::vi2d(4, 4), pIcon.Decal(),sprOffset,sprSize);
} }
#pragma endregion #pragma endregion
#pragma region ImageCheckBox #pragma region ImageCheckBox
ImageCheckBox::ImageCheckBox(olc::QuickGUI::Manager& manager, const olc::Renderable& gfx, const bool check, const olc::vf2d& pos, const olc::vf2d& size) ImageCheckBox::ImageCheckBox(olc::QuickGUI::Manager& manager, const olc::Renderable& gfx, const bool check, const olc::vf2d& pos, const olc::vf2d& size,const olc::vi2d& sprOffset,const olc::vi2d& sprSize)
: ImageButton(manager, gfx, pos, size) : ImageButton(manager, gfx, pos, size,sprOffset,sprSize)
{ {
bChecked = check; bChecked = check;
} }
@ -807,17 +877,48 @@ namespace olc::QuickGUI
if (!bVisible) if (!bVisible)
return; return;
ImageButton::DrawDecal(pge);
if (bChecked) if (bChecked)
{ {
pge->SetDecalMode(olc::DecalMode::WIREFRAME);
pge->FillRectDecal(vPos + olc::vf2d(2, 2), vSize - olc::vf2d(4, 4), m_manager.colBorder);
pge->SetDecalMode(olc::DecalMode::NORMAL);
ImageButton::DrawDecal(pge);
}
switch (m_state)
{
case State::Disabled:
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colDisable);
break;
case State::Normal:
case State::Hover:
if(bChecked){
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), olc::PixelLerp(m_manager.colSelected, m_manager.colHover, m_fTransition));
} else {
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), olc::PixelLerp(m_manager.colNormal, m_manager.colHover, m_fTransition));
}
break;
case State::Click:
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colClick); pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colClick);
pge->DrawDecal(vPos + olc::vi2d(4, 4), pIcon.Decal()); break;
} }
pge->DrawPartialDecal(vPos + olc::vi2d(4, 4), pIcon.Decal(),sprOffset,sprSize);
pge->SetDecalMode(olc::DecalMode::WIREFRAME); pge->SetDecalMode(olc::DecalMode::WIREFRAME);
pge->FillRectDecal(vPos + olc::vf2d(2, 2), vSize - olc::vf2d(4, 4), m_manager.colBorder); pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colBorder);
pge->SetDecalMode(olc::DecalMode::NORMAL);
if (bChecked)
{
pge->SetDecalMode(olc::DecalMode::WIREFRAME);
for(int i=0;i<4;i++){
pge->FillRectDecal(vPos + olc::vf2d(2, 2) + olc::vf2d(i,i)/2, vSize - olc::vf2d(4, 4) - olc::vf2d(i*2,i*2)/2, m_manager.colBorderSelected);
}
pge->SetDecalMode(olc::DecalMode::NORMAL); pge->SetDecalMode(olc::DecalMode::NORMAL);
}
olc::vf2d vText = pge->GetTextSizeProp(sText); olc::vf2d vText = pge->GetTextSizeProp(sText);
pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText); pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
@ -902,14 +1003,17 @@ namespace olc::QuickGUI
{ {
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn; m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
m_state = State::Hover; m_state = State::Hover;
bHovered = true;
if (pge->GetMouse(olc::Mouse::LEFT).bPressed) if (pge->GetMouse(olc::Mouse::LEFT).bPressed)
{ {
m_state = State::Click; m_state = State::Click;
bPressed = true; bPressed = true;
} }
} }
else else {
m_state = State::Normal; m_state = State::Normal;
bHovered = false;
}
} }
if (pge->GetMouse(olc::Mouse::LEFT).bReleased) if (pge->GetMouse(olc::Mouse::LEFT).bReleased)
@ -986,8 +1090,8 @@ namespace olc::QuickGUI
#pragma endregion #pragma endregion
#pragma region ListBox #pragma region ListBox
ListBox::ListBox(olc::QuickGUI::Manager& manager, std::vector<std::string>& vList, const olc::vf2d& pos, const olc::vf2d& size) ListBox::ListBox(olc::QuickGUI::Manager& manager, std::vector<std::string>& vList, const olc::vf2d& pos, const olc::vf2d& size, const float fontSize)
: BaseControl(manager), m_vList(vList) : BaseControl(manager), m_vList(vList), fontSize(fontSize)
{ {
m_group.CopyThemeFrom(m_manager); m_group.CopyThemeFrom(m_manager);
vPos = pos; vPos = pos;
@ -1001,15 +1105,17 @@ namespace olc::QuickGUI
if (m_state == State::Disabled || !bVisible) if (m_state == State::Disabled || !bVisible)
return; return;
nPreviouslySelectedItem = nSelectedItem; nPreviouslySelectedItem = nSelectedItem;
olc::vf2d vMouse = pge->GetMousePos() - vPos + olc::vi2d(2,0); olc::vf2d vMouse = pge->GetMousePos() - vPos + olc::vi2d(2,0);
if (pge->GetMouse(olc::Mouse::LEFT).bPressed)
bHovered=pge->GetMouseX() >= vPos.x && pge->GetMouseX() < vPos.x + vSize.x &&
pge->GetMouseY() >= vPos.y && pge->GetMouseY() < vPos.y + vSize.y;
if (pge->GetMouse(olc::Mouse::LEFT).bHeld)
{ {
if (vMouse.x >= 0 && vMouse.x < vSize.x - (m_group.fGrabRad * 2) && vMouse.y >= 0 && vMouse.y < vSize.y) if (vMouse.x >= 0 && vMouse.x < vSize.x - (m_group.fGrabRad * 2) && vMouse.y >= 0 && vMouse.y < vSize.y)
{ {
nSelectedItem = size_t(m_pSlider->fValue + vMouse.y / fontSize);
nSelectedItem = size_t(m_pSlider->fValue + vMouse.y / 10);
} }
} }
@ -1018,7 +1124,18 @@ namespace olc::QuickGUI
bSelectionChanged = nSelectedItem != nPreviouslySelectedItem; bSelectionChanged = nSelectedItem != nPreviouslySelectedItem;
m_pSlider->fMax = float(m_vList.size()); m_pSlider->fMax = float(m_vList.size()-vSize.y/fontSize+1);
if(bHovered&&pge->GetMouseWheel()!=0){
if(pge->GetMouseWheel()>0){
m_pSlider->fValue=std::clamp(m_pSlider->fValue-1, m_pSlider->fMin, m_pSlider->fMax);
} else {
m_pSlider->fValue=std::clamp(m_pSlider->fValue+1, m_pSlider->fMin, m_pSlider->fMax);
}
}
m_pSlider->fValue=int(m_pSlider->fValue);
m_group.Update(pge); m_group.Update(pge);
} }
@ -1037,15 +1154,15 @@ namespace olc::QuickGUI
size_t idx0 = size_t(m_pSlider->fValue); size_t idx0 = size_t(m_pSlider->fValue);
size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / 10), m_vList.size()); size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / fontSize), m_vList.size());
olc::vf2d vTextPos = vPos + olc::vf2d(2,2); olc::vf2d vTextPos = vPos + olc::vf2d(2,2);
for (size_t idx = idx0; idx < idx1; idx++) for (size_t idx = idx0; idx < idx1; idx++)
{ {
if (idx == nSelectedItem) if (idx == nSelectedItem)
pge->FillRect(vTextPos - olc::vi2d(1,1), {int32_t(vSize.x - m_group.fGrabRad * 2), 10}, m_group.colHover); pge->FillRect(vTextPos - olc::vi2d(1,-1), {int32_t(vSize.x - m_group.fGrabRad * 2), int(fontSize)}, m_group.colHover);
pge->DrawStringProp(vTextPos, m_vList[idx]); pge->DrawStringProp(vTextPos + olc::vi2d(0,2), m_vList[idx],olc::WHITE,fontSize/10);
vTextPos.y += 10; vTextPos.y += fontSize;
} }
m_group.Draw(pge); m_group.Draw(pge);
@ -1060,15 +1177,21 @@ namespace olc::QuickGUI
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colNormal); pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colNormal);
size_t idx0 = size_t(m_pSlider->fValue); size_t idx0 = size_t(m_pSlider->fValue);
size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / 10), m_vList.size()); size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / fontSize), m_vList.size());
olc::vf2d vTextPos = vPos + olc::vf2d(2, 2); olc::vf2d vTextPos = vPos + olc::vf2d(2, 2);
for (size_t idx = idx0; idx < idx1; idx++) for (size_t idx = idx0; idx < idx1; idx++)
{ {
if (idx == nSelectedItem) if (idx == nSelectedItem)
pge->FillRectDecal(vTextPos - olc::vi2d(1, 1), { vSize.x - m_group.fGrabRad * 2.0f, 10.0f }, m_group.colHover); pge->FillRectDecal(vTextPos - olc::vi2d(1, -1), { vSize.x - m_group.fGrabRad * 2.0f, fontSize }, m_group.colHover);
pge->DrawStringPropDecal(vTextPos, m_vList[idx]); float width = pge->GetTextSizeProp(m_vList[idx]).x*fontSize/10;
vTextPos.y += 10; if (width>vSize.x-m_manager.fGrabRad*2){
float scaleX = (vSize.x-m_manager.fGrabRad*2)/width;
pge->DrawStringPropDecal(vTextPos + olc::vi2d(0,2), m_vList[idx], olc::WHITE, olc::vf2d{scaleX,1}*fontSize/10);
} else {
pge->DrawStringPropDecal(vTextPos + olc::vi2d(0,2), m_vList[idx], olc::WHITE, olc::vf2d{1,1}*fontSize/10);
}
vTextPos.y += fontSize;
} }
if (bHasBorder) if (bHasBorder)

Loading…
Cancel
Save