generated from sigonasr2/CPlusPlusProjectTemplate
Add in new and edit buttons. Add delete functionality.
This commit is contained in:
parent
4c5781d0c9
commit
121845a4af
BIN
TiledCollisionEditor/EditButton.png
Normal file
BIN
TiledCollisionEditor/EditButton.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 768 B |
@ -6,6 +6,7 @@
|
||||
|
||||
using namespace olc;
|
||||
using namespace olc::utils;
|
||||
using namespace QuickGUI;
|
||||
|
||||
const std::string TILESET_DIR="./Tiles/";
|
||||
|
||||
@ -23,6 +24,8 @@ class TiledCollisionEditor : public olc::PixelGameEngine
|
||||
vf2d upperLeftDragOffset{};
|
||||
|
||||
Renderable circle;
|
||||
Renderable createNewButtonImg;
|
||||
Renderable editButtonImg;
|
||||
|
||||
TransformedView view;
|
||||
|
||||
@ -34,6 +37,11 @@ public:
|
||||
|
||||
Renderable rollingCounter;
|
||||
|
||||
Manager gui;
|
||||
|
||||
ImageCheckBox*createNewButton;
|
||||
ImageCheckBox*editButton;
|
||||
|
||||
public:
|
||||
bool OnUserCreate() override
|
||||
{
|
||||
@ -46,6 +54,9 @@ public:
|
||||
SetDrawTarget(nullptr);
|
||||
circle.Decal()->Update();
|
||||
|
||||
createNewButtonImg.Load("newCollisionButton.png");
|
||||
editButtonImg.Load("EditButton.png");
|
||||
|
||||
std::string tilesetFilename=TILESET_DIR+"Basic Tileset.tsx";
|
||||
Tileset&tileset=tilesets[tilesetFilename]=TSXParser{tilesetFilename}.GetData();
|
||||
|
||||
@ -55,6 +66,11 @@ public:
|
||||
tilesetImg.Load(TILESET_DIR+tileset.filename);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -65,42 +81,9 @@ public:
|
||||
float currentHealth=0;
|
||||
float targetHealth=60;
|
||||
|
||||
bool OnUserUpdate(float fElapsedTime) override
|
||||
{
|
||||
Clear(VERY_DARK_BLUE);
|
||||
|
||||
view.HandlePanAndZoom();
|
||||
|
||||
void Update(){
|
||||
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){
|
||||
for(int y=0;y<tileset.tilecount/tileset.columns;y++){
|
||||
for(int x=0;x<tileset.columns;x++){
|
||||
@ -140,22 +123,66 @@ public:
|
||||
pointInd++;
|
||||
}
|
||||
}
|
||||
|
||||
if(GetMouse(Mouse::LEFT).bPressed){
|
||||
#pragma region Select a point on a collision quad.
|
||||
for(const Quadrilateral&quad:obj.collisionTiles){
|
||||
for(size_t pointInd=0;const vf2d&point:quad){
|
||||
if(geom2d::line<float>(point,view.ScreenToWorld(GetMousePos())).length()<4){
|
||||
if(GetMouse(Mouse::LEFT).bPressed){
|
||||
editingPoint=pointInd;
|
||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
||||
if(editButton->bChecked){
|
||||
if(GetMouse(Mouse::LEFT).bPressed){
|
||||
#pragma region Select a point on a collision quad.
|
||||
for(const Quadrilateral&quad:obj.collisionTiles){
|
||||
for(size_t pointInd=0;const vf2d&point:quad){
|
||||
if(geom2d::line<float>(point,view.ScreenToWorld(GetMousePos())).length()<4){
|
||||
if(GetMouse(Mouse::LEFT).bPressed){
|
||||
editingPoint=pointInd;
|
||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
||||
originalQuad=quad;
|
||||
}
|
||||
goto exitCollisionCheck;
|
||||
}
|
||||
goto exitCollisionCheck;
|
||||
pointInd++;
|
||||
}
|
||||
pointInd++;
|
||||
}
|
||||
#pragma endregion
|
||||
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()))){
|
||||
dragTranslate=true;
|
||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
||||
upperLeftDragOffset=GetSnapPoint()-quad[0];
|
||||
originalQuad=*editingQuad;
|
||||
goto exitCollisionCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
exitCollisionCheck:
|
||||
if(EditingQuad&&!dragging){
|
||||
(*editingQuad)[editingPoint]=GetSnapPoint();
|
||||
editingPoint++;
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
if(GetMouse(Mouse::RIGHT).bPressed||GetKey(ESCAPE).bPressed){
|
||||
if(EditingQuad||dragTranslate){
|
||||
editingPoint=4;
|
||||
dragging=false;
|
||||
*editingQuad=originalQuad;
|
||||
editingQuad=nullptr;
|
||||
dragTranslate=false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(GetMouse(Mouse::LEFT).bPressed){
|
||||
Quadrilateral newQuad{GetSnapPoint()};
|
||||
tilesets[activeTileset].objects[selectedObj].collisionTiles.push_back(newQuad);
|
||||
dragging=true;
|
||||
editingQuad=const_cast<Quadrilateral*>(&obj.collisionTiles.back());
|
||||
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]},
|
||||
@ -163,26 +190,15 @@ public:
|
||||
};
|
||||
for(geom2d::triangle<float>&tri:collisionTris){
|
||||
if(geom2d::contains(tri,view.ScreenToWorld(GetMousePos()))){
|
||||
dragTranslate=true;
|
||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
||||
upperLeftDragOffset=GetSnapPoint()-quad[0];
|
||||
originalQuad=*editingQuad;
|
||||
goto exitCollisionCheck;
|
||||
//Delete this quad, the mouse is overlapping it!
|
||||
quadsToBeRemoved.push_back(const_cast<Quadrilateral*>(&quad));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exitCollisionCheck:
|
||||
if(EditingQuad&&!dragging){
|
||||
(*editingQuad)[editingPoint]=GetSnapPoint();
|
||||
editingPoint++;
|
||||
}else{
|
||||
if(obj.collisionTiles.size()==0){
|
||||
Quadrilateral newQuad{GetSnapPoint()};
|
||||
tilesets[activeTileset].objects[selectedObj].collisionTiles.push_back(newQuad);
|
||||
dragging=true;
|
||||
editingQuad=const_cast<Quadrilateral*>(&obj.collisionTiles.back());
|
||||
originalQuad=*editingQuad;
|
||||
}
|
||||
|
||||
for(Quadrilateral*quad:quadsToBeRemoved){
|
||||
std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==quad;});
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,23 +217,72 @@ public:
|
||||
}
|
||||
dragTranslate=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(GetMouse(Mouse::RIGHT).bPressed||GetKey(ESCAPE).bPressed){
|
||||
if(EditingQuad){
|
||||
editingPoint=4;
|
||||
dragging=false;
|
||||
*editingQuad=originalQuad;
|
||||
editingQuad=nullptr;
|
||||
bool OnUserUpdate(float fElapsedTime) override
|
||||
{
|
||||
Clear(VERY_DARK_BLUE);
|
||||
|
||||
view.HandlePanAndZoom();
|
||||
|
||||
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){
|
||||
std::vector<vf2d>points;
|
||||
std::vector<vf2d>uvs;
|
||||
std::vector<Pixel>cols;
|
||||
points.assign(quad.begin(),quad.end());
|
||||
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);
|
||||
|
||||
for(bool highlighted=false;const vf2d&point:quad){
|
||||
@ -230,13 +295,28 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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});
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
gui.Update(this);
|
||||
gui.DrawDecal(this);
|
||||
|
||||
DrawStringDecal(createNewButton->vPos+vf2d{3,0},"Q");
|
||||
DrawStringDecal(editButton->vPos+vf2d{3,0},"E");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
BIN
TiledCollisionEditor/newCollisionButton.png
Normal file
BIN
TiledCollisionEditor/newCollisionButton.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 672 B |
@ -1,74 +1,73 @@
|
||||
/*
|
||||
OneLoneCoder - QuickGUI v1.03
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
A semi-immediate mode GUI for very simple GUI stuff.
|
||||
Includes:
|
||||
Label - Displays a single-line string
|
||||
TextBox - Click to enter/edit single-line text
|
||||
Button - A clickable labelled rectangle
|
||||
CheckBox - A clickable labelled rectangle that retains state
|
||||
ImageButton - A Button with an image instead of text
|
||||
ImageCheckBox- A CheckBox with an image instead of text
|
||||
Slider - An omnidirectional draggable handle between two values
|
||||
ListBox - A list of strings, that can be scrolled and an item selected
|
||||
/*
|
||||
OneLoneCoder - QuickGUI v1.02
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
A semi-immediate mode GUI for very simple GUI stuff.
|
||||
Includes:
|
||||
Label - Displays a single-line string
|
||||
TextBox - Click to enter/edit single-line text
|
||||
Button - A clickable labelled rectangle
|
||||
CheckBox - A clickable labelled rectangle that retains state
|
||||
ImageButton - A Button with an image instead of text
|
||||
ImageCheckBox- A CheckBox with an image instead of text
|
||||
Slider - An omnidirectional draggable handle between two values
|
||||
ListBox - A list of strings, that can be scrolled and an item selected
|
||||
|
||||
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
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above
|
||||
copyright notice, this list of conditions and the following disclaimer.
|
||||
1. Redistributions or derivations of source code must retain the above
|
||||
copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce
|
||||
the above copyright notice. This list of conditions and the following
|
||||
disclaimer must be reproduced in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
2. Redistributions or derivative works in binary form must reproduce
|
||||
the above copyright notice. This list of conditions and the following
|
||||
disclaimer must be reproduced in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Links
|
||||
~~~~~
|
||||
YouTube: https://www.youtube.com/javidx9
|
||||
Discord: https://discord.gg/WhwHUMV
|
||||
Twitter: https://www.twitter.com/javidx9
|
||||
Twitch: https://www.twitch.tv/javidx9
|
||||
GitHub: https://www.github.com/onelonecoder
|
||||
Homepage: https://www.onelonecoder.com
|
||||
Links
|
||||
~~~~~
|
||||
YouTube: https://www.youtube.com/javidx9
|
||||
Discord: https://discord.gg/WhwHUMV
|
||||
Twitter: https://www.twitter.com/javidx9
|
||||
Twitch: https://www.twitch.tv/javidx9
|
||||
GitHub: https://www.github.com/onelonecoder
|
||||
Homepage: https://www.onelonecoder.com
|
||||
|
||||
Author
|
||||
~~~~~~
|
||||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022, 2023, 2024
|
||||
Author
|
||||
~~~~~~
|
||||
David Barr, aka javidx9, <EFBFBD>OneLoneCoder 2019, 2020, 2021, 2022
|
||||
|
||||
Changes
|
||||
~~~~~~~
|
||||
v1.01 +Moved Slider::fGrabRad into "theme"
|
||||
+Manager::CopyThemeFrom() - copies theme attributes from a different manager
|
||||
+ListBox - Displays a vector of strings
|
||||
v1.02 +ImageButton
|
||||
+ImageCheckBox
|
||||
+ListBox::bSelectionChanged flag, true when list selected item changes
|
||||
=Fix - Text box mouse behaviours, mouse release is now meaningless
|
||||
+CheckBox Fix for decal display
|
||||
v1.03 =Fix ImageCheckBox
|
||||
Changes
|
||||
~~~~~~~
|
||||
v1.01 +Moved Slider::fGrabRad into "theme"
|
||||
+Manager::CopyThemeFrom() - copies theme attributes from a different manager
|
||||
+ListBox - Displays a vector of strings
|
||||
v1.02 +ImageButton
|
||||
+ImageCheckBox
|
||||
+ListBox::bSelectionChanged flag, true when list selected item changes
|
||||
=Fix - Text box mouse behaviours, mouse release is now meaningless
|
||||
+CheckBox Fix for decal display
|
||||
|
||||
*/
|
||||
|
||||
@ -101,6 +100,8 @@ namespace olc::QuickGUI
|
||||
bool bHeld = false;
|
||||
// True on single frame control ceases being manipulated
|
||||
bool bReleased = false;
|
||||
// true on all frames control is being hovered over
|
||||
bool bHovered = false;
|
||||
|
||||
public:
|
||||
// Updates the controls behvaiour
|
||||
@ -121,7 +122,7 @@ namespace olc::QuickGUI
|
||||
// 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;
|
||||
};
|
||||
@ -135,7 +136,7 @@ namespace olc::QuickGUI
|
||||
// given to this manager via AddControl() if true
|
||||
Manager(const bool bCleanUpForMe = true);
|
||||
virtual ~Manager();
|
||||
|
||||
|
||||
public:
|
||||
// Add a gui element derived form BaseControl to this manager
|
||||
void AddControl(BaseControl* control);
|
||||
@ -145,15 +146,17 @@ namespace olc::QuickGUI
|
||||
void Draw(olc::PixelGameEngine* pge);
|
||||
// Draws as "decal" all controls this manager operates
|
||||
void DrawDecal(olc::PixelGameEngine* pge);
|
||||
|
||||
|
||||
public: // This managers "Theme" can be set here
|
||||
// Various element colours
|
||||
olc::Pixel colNormal = olc::DARK_BLUE;
|
||||
olc::Pixel colHover = olc::BLUE;
|
||||
olc::Pixel colClick = olc::CYAN;
|
||||
olc::Pixel colDisable = olc::DARK_GREY;
|
||||
olc::Pixel colBorder = olc::WHITE;
|
||||
olc::Pixel colText = olc::WHITE;
|
||||
olc::Pixel colNormal = {45, 0, 105};
|
||||
olc::Pixel colSelected = {183, 99, 201};
|
||||
olc::Pixel colHover = {173, 127, 235};
|
||||
olc::Pixel colClick = {129, 36, 255};
|
||||
olc::Pixel colDisable = {93, 87, 102};
|
||||
olc::Pixel colBorder = {209, 209, 209};
|
||||
olc::Pixel colBorderSelected = {63, 35, 84};
|
||||
olc::Pixel colText = {209, 209, 209};
|
||||
// Speed to transiton from Normal -> Hover
|
||||
float fHoverSpeedOn = 10.0f;
|
||||
// Speed to transiton from Hover -> Normal
|
||||
@ -207,16 +210,17 @@ namespace olc::QuickGUI
|
||||
TextBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
|
||||
const std::string& text, // Text to display
|
||||
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
|
||||
void Update(olc::PixelGameEngine* pge) override;
|
||||
void Draw(olc::PixelGameEngine* pge) override;
|
||||
void DrawDecal(olc::PixelGameEngine* pge) override;
|
||||
|
||||
protected:
|
||||
bool m_bTextEdit = false;
|
||||
|
||||
protected:
|
||||
vf2d fontSize;
|
||||
};
|
||||
|
||||
// Creates a Button Control - a clickable, labelled rectangle
|
||||
@ -226,8 +230,9 @@ namespace olc::QuickGUI
|
||||
Button(olc::QuickGUI::Manager& manager, // Associate with a Manager
|
||||
const std::string& text, // Text to display
|
||||
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:
|
||||
// Position of button
|
||||
olc::vf2d vPos;
|
||||
@ -235,6 +240,8 @@ namespace olc::QuickGUI
|
||||
olc::vf2d vSize;
|
||||
// Text displayed on button
|
||||
std::string sText;
|
||||
olc::vf2d fontScale;
|
||||
Key hotkey{NONE};
|
||||
|
||||
public: // BaseControl overrides
|
||||
void Update(olc::PixelGameEngine* pge) override;
|
||||
@ -261,16 +268,41 @@ namespace olc::QuickGUI
|
||||
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
|
||||
{
|
||||
public:
|
||||
ImageButton(olc::QuickGUI::Manager& manager, // Associate with a Manager
|
||||
const olc::Renderable &icon, // Text to display
|
||||
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:
|
||||
const olc::Renderable& pIcon;
|
||||
olc::vi2d sprOffset;
|
||||
olc::vi2d sprSize;
|
||||
|
||||
public:
|
||||
void Draw(olc::PixelGameEngine* pge) override;
|
||||
@ -284,7 +316,9 @@ namespace olc::QuickGUI
|
||||
const olc::Renderable& icon, // Text to display
|
||||
const bool check, // Is checked or not?
|
||||
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:
|
||||
bool bChecked = false;
|
||||
@ -333,7 +367,8 @@ namespace olc::QuickGUI
|
||||
ListBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
|
||||
std::vector<std::string>& vList,
|
||||
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
|
||||
olc::vf2d vPos;
|
||||
@ -343,12 +378,13 @@ namespace olc::QuickGUI
|
||||
bool bHasBorder = true;
|
||||
// Show a background?
|
||||
bool bHasBackground = true;
|
||||
|
||||
|
||||
public:
|
||||
Slider *m_pSlider = nullptr;
|
||||
Manager m_group;
|
||||
size_t m_nVisibleItems = 0;
|
||||
std::vector<std::string>& m_vList;
|
||||
float fontSize=10;
|
||||
|
||||
public:
|
||||
// Item currently selected
|
||||
@ -468,7 +504,7 @@ namespace olc::QuickGUI
|
||||
{
|
||||
vPos = pos; vSize = size; sText = text;
|
||||
}
|
||||
|
||||
|
||||
void Label::Update(olc::PixelGameEngine* pge)
|
||||
{
|
||||
|
||||
@ -537,8 +573,8 @@ namespace olc::QuickGUI
|
||||
|
||||
|
||||
#pragma region TextBox
|
||||
TextBox::TextBox(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size)
|
||||
: Label(manager, text, pos, 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),fontSize(fontSize)
|
||||
{
|
||||
nAlign = Alignment::Left;
|
||||
bHasBorder = true;
|
||||
@ -552,9 +588,15 @@ namespace olc::QuickGUI
|
||||
|
||||
bPressed = false;
|
||||
bReleased = false;
|
||||
|
||||
|
||||
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 &&
|
||||
vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
|
||||
{
|
||||
@ -568,7 +610,7 @@ namespace olc::QuickGUI
|
||||
pge->TextEntryEnable(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bPressed && !pge->IsTextEntryEnabled() && !m_bTextEdit)
|
||||
{
|
||||
pge->TextEntryEnable(true, sText);
|
||||
@ -577,7 +619,6 @@ namespace olc::QuickGUI
|
||||
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -585,14 +626,14 @@ namespace olc::QuickGUI
|
||||
bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed;
|
||||
bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
|
||||
|
||||
if (bPressed && m_bTextEdit)
|
||||
|
||||
if (bPressed && m_bTextEdit && pge->IsTextEntryEnabled())
|
||||
{
|
||||
sText = pge->TextEntryGetString();
|
||||
pge->TextEntryEnable(false);
|
||||
m_bTextEdit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bTextEdit && pge->IsTextEntryEnabled())
|
||||
sText = pge->TextEntryGetString();
|
||||
@ -618,11 +659,11 @@ namespace olc::QuickGUI
|
||||
olc::vf2d vCursorPos = pge->GetTextSizeProp(sText.substr(0, i));
|
||||
pge->FillRect(olc::vf2d(vPos.x + 2.0f + vCursorPos.x, (vPos.y + (vSize.y - 10.0f) * 0.5f)), { 2, 10 }, m_manager.colText);
|
||||
}
|
||||
|
||||
|
||||
// Draw Text
|
||||
olc::vf2d vText = pge->GetTextSizeProp(sText);
|
||||
pge->DrawStringProp(olc::vf2d(vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f), sText, m_manager.colText);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TextBox::DrawDecal(olc::PixelGameEngine* pge)
|
||||
@ -646,19 +687,19 @@ namespace olc::QuickGUI
|
||||
{
|
||||
// Draw Cursor
|
||||
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);
|
||||
}
|
||||
|
||||
// Draw Text
|
||||
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 region Button
|
||||
Button::Button(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size)
|
||||
: BaseControl(manager)
|
||||
Button::Button(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size, const olc::vf2d& fontScale)
|
||||
: BaseControl(manager),fontScale(fontScale)
|
||||
{
|
||||
vPos = pos; vSize = size; sText = text;
|
||||
}
|
||||
@ -676,29 +717,32 @@ namespace olc::QuickGUI
|
||||
if (m_state != State::Click)
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
m_state = State::Click;
|
||||
}
|
||||
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld||pge->GetKey(hotkey).bHeld;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
|
||||
m_state = State::Normal;
|
||||
bHovered = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
|
||||
bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
|
||||
bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld||pge->GetKey(hotkey).bHeld;
|
||||
bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased||pge->GetKey(hotkey).bReleased;
|
||||
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->SetDecalMode(olc::DecalMode::NORMAL);
|
||||
|
||||
olc::vf2d vText = pge->GetTextSizeProp(sText);
|
||||
pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
|
||||
olc::vf2d vText = pge->GetTextSizeProp(sText)*fontScale;
|
||||
pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText,fontScale);
|
||||
}
|
||||
#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)
|
||||
{}
|
||||
|
||||
void CustomButton::DrawDecal(olc::PixelGameEngine* pge)
|
||||
{
|
||||
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)
|
||||
: Button(manager, "", pos, size), pIcon(icon)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 region ImageCheckBox
|
||||
ImageCheckBox::ImageCheckBox(olc::QuickGUI::Manager& manager, const olc::Renderable& gfx, const bool check, const olc::vf2d& pos, const olc::vf2d& size)
|
||||
: ImageButton(manager, gfx, pos, 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,sprOffset,sprSize)
|
||||
{
|
||||
bChecked = check;
|
||||
}
|
||||
@ -807,18 +877,49 @@ namespace olc::QuickGUI
|
||||
if (!bVisible)
|
||||
return;
|
||||
|
||||
ImageButton::DrawDecal(pge);
|
||||
|
||||
|
||||
if (bChecked)
|
||||
{
|
||||
pge->FillRectDecal(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colClick);
|
||||
pge->DrawDecal(vPos + olc::vi2d(4, 4), pIcon.Decal());
|
||||
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);
|
||||
break;
|
||||
}
|
||||
pge->DrawPartialDecal(vPos + olc::vi2d(4, 4), pIcon.Decal(),sprOffset,sprSize);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
olc::vf2d vText = pge->GetTextSizeProp(sText);
|
||||
pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
|
||||
}
|
||||
@ -883,7 +984,7 @@ namespace olc::QuickGUI
|
||||
{
|
||||
if (m_state == State::Disabled || !bVisible)
|
||||
return;
|
||||
|
||||
|
||||
float fElapsedTime = pge->GetElapsedTime();
|
||||
|
||||
olc::vf2d vMouse = pge->GetMousePos();
|
||||
@ -902,14 +1003,17 @@ namespace olc::QuickGUI
|
||||
{
|
||||
m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
|
||||
m_state = State::Hover;
|
||||
bHovered = true;
|
||||
if (pge->GetMouse(olc::Mouse::LEFT).bPressed)
|
||||
{
|
||||
m_state = State::Click;
|
||||
bPressed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
m_state = State::Normal;
|
||||
bHovered = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pge->GetMouse(olc::Mouse::LEFT).bReleased)
|
||||
@ -986,8 +1090,8 @@ namespace olc::QuickGUI
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ListBox
|
||||
ListBox::ListBox(olc::QuickGUI::Manager& manager, std::vector<std::string>& vList, const olc::vf2d& pos, const olc::vf2d& size)
|
||||
: BaseControl(manager), m_vList(vList)
|
||||
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), fontSize(fontSize)
|
||||
{
|
||||
m_group.CopyThemeFrom(m_manager);
|
||||
vPos = pos;
|
||||
@ -1001,15 +1105,17 @@ namespace olc::QuickGUI
|
||||
if (m_state == State::Disabled || !bVisible)
|
||||
return;
|
||||
|
||||
|
||||
nPreviouslySelectedItem = nSelectedItem;
|
||||
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)
|
||||
{
|
||||
|
||||
nSelectedItem = size_t(m_pSlider->fValue + vMouse.y / 10);
|
||||
nSelectedItem = size_t(m_pSlider->fValue + vMouse.y / fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1018,7 +1124,18 @@ namespace olc::QuickGUI
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1037,15 +1154,15 @@ namespace olc::QuickGUI
|
||||
|
||||
|
||||
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);
|
||||
for (size_t idx = idx0; idx < idx1; idx++)
|
||||
{
|
||||
if (idx == nSelectedItem)
|
||||
pge->FillRect(vTextPos - olc::vi2d(1,1), {int32_t(vSize.x - m_group.fGrabRad * 2), 10}, m_group.colHover);
|
||||
pge->DrawStringProp(vTextPos, m_vList[idx]);
|
||||
vTextPos.y += 10;
|
||||
pge->FillRect(vTextPos - olc::vi2d(1,-1), {int32_t(vSize.x - m_group.fGrabRad * 2), int(fontSize)}, m_group.colHover);
|
||||
pge->DrawStringProp(vTextPos + olc::vi2d(0,2), m_vList[idx],olc::WHITE,fontSize/10);
|
||||
vTextPos.y += fontSize;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
for (size_t idx = idx0; idx < idx1; idx++)
|
||||
{
|
||||
if (idx == nSelectedItem)
|
||||
pge->FillRectDecal(vTextPos - olc::vi2d(1, 1), { vSize.x - m_group.fGrabRad * 2.0f, 10.0f }, m_group.colHover);
|
||||
pge->DrawStringPropDecal(vTextPos, m_vList[idx]);
|
||||
vTextPos.y += 10;
|
||||
pge->FillRectDecal(vTextPos - olc::vi2d(1, -1), { vSize.x - m_group.fGrabRad * 2.0f, fontSize }, m_group.colHover);
|
||||
float width = pge->GetTextSizeProp(m_vList[idx]).x*fontSize/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)
|
||||
@ -1126,17 +1249,17 @@ namespace olc::QuickGUI
|
||||
{
|
||||
std::string sDirectory = m_vDirectory[m_listDirectory->nSelectedItem];
|
||||
/*if (sDirectory == "..")
|
||||
m_path = m_path.parent_path().string() + "/";
|
||||
m_path = m_path.parent_path().string() + "/";
|
||||
else
|
||||
m_path += sDirectory+ "/";*/
|
||||
|
||||
m_path += sDirectory+ "/";*/
|
||||
|
||||
|
||||
m_path += sDirectory + "/";
|
||||
// Reconstruct Lists
|
||||
m_vDirectory.clear();
|
||||
|
||||
|
||||
m_vFiles.clear();
|
||||
|
||||
|
||||
|
||||
for (auto const& dir_entry : std::filesystem::directory_iterator{ m_path })
|
||||
{
|
||||
@ -1153,7 +1276,7 @@ namespace olc::QuickGUI
|
||||
|
||||
}
|
||||
|
||||
pge->DrawStringDecal({ 0,0 }, m_path.string());
|
||||
pge->DrawStringDecal({ 0,0 }, m_path.string());
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user