Added pause menu, new F3 debug panel, fogCurve setting

This commit is contained in:
MihailRis
2023-11-11 15:35:27 +03:00
parent b9ed7a2b28
commit e48e41c99a
28 changed files with 1267 additions and 324 deletions
+85
View File
@@ -0,0 +1,85 @@
#include "GUI.h"
#include "UINode.h"
#include "panels.h"
#include <iostream>
#include "../../assets/Assets.h"
#include "../../graphics/Batch2D.h"
#include "../../window/Events.h"
#include "../../window/input.h"
using std::shared_ptr;
using namespace gui;
GUI::GUI() {
container = new Container(vec2(0, 0), vec2(Window::width, Window::height));
}
GUI::~GUI() {
delete container;
}
void GUI::act() {
container->size(vec2(Window::width, Window::height));
int mx = Events::x;
int my = Events::y;
auto hover = container->getAt(vec2(mx, my), nullptr);
if (this->hover && this->hover != hover) {
this->hover->hover(false);
}
if (hover) {
hover->hover(true);
}
this->hover = hover;
if (Events::clicked(0)) {
if (pressed == nullptr && this->hover) {
pressed = hover;
pressed->click(this, mx, my);
if (focus) {
focus->defocus();
}
focus = pressed;
}
if (this->hover == nullptr && focus) {
focus->defocus();
focus = nullptr;
}
} else if (pressed) {
pressed->mouseRelease(this, mx, my);
pressed = nullptr;
}
if (focus) {
if (!focus->isfocused()){
focus = nullptr;
} else if (Events::jpressed(keycode::ESCAPE)) {
focus->defocus();
focus = nullptr;
} else {
for (auto codepoint : Events::codepoints) {
focus->typed(codepoint);
}
for (auto key : Events::pressedKeys) {
focus->keyPressed(key);
}
}
}
}
void GUI::draw(Batch2D* batch, Assets* assets) {
container->draw(batch, assets);
}
shared_ptr<UINode> GUI::getFocused() const {
return focus;
}
bool GUI::isFocusCaught() const {
return focus && focus->isfocuskeeper();
}
void GUI::add(shared_ptr<UINode> panel) {
container->add(panel);
}
+64
View File
@@ -0,0 +1,64 @@
#ifndef FRONTEND_GUI_GUI_H_
#define FRONTEND_GUI_GUI_H_
#include <memory>
#include <vector>
#include <glm/glm.hpp>
class Batch2D;
class Assets;
/*
Some info about padding and margin.
Padding is element inner space, margin is outer
glm::vec4 usage:
x - left
y - top
z - right
w - bottom
Outer element
+======================================================================+
| . . . . |
| .padding.y . . . |
| padding.x . . . . padding.z |
|- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - |
| . . . . |
| . .margin.y . . |
| .margin.x . . margin.z. |
|- - - - - - + - - - - - +====================+- - - - - + - - - - - - |
| . | Inner element | . |
|- - - - - - + - - - - - +====================+- - - - - + - - - - - - |
| . . . . |
| . .margin.w . . |
| . . . . |
|- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - |
| . . . . |
| .padding.w . . . |
| . . . . |
+======================================================================+
*/
namespace gui {
class UINode;
class Container;
class GUI {
Container* container;
std::shared_ptr<UINode> hover = nullptr;
std::shared_ptr<UINode> pressed = nullptr;
std::shared_ptr<UINode> focus = nullptr;
public:
GUI();
~GUI();
std::shared_ptr<UINode> getFocused() const;
bool isFocusCaught() const;
void act();
void draw(Batch2D* batch, Assets* assets);
void add(std::shared_ptr<UINode> panel);
};
}
#endif // FRONTEND_GUI_GUI_H_
+24
View File
@@ -0,0 +1,24 @@
#include "Panel.h"
#include "../../graphics/Batch2D.h"
using gui::Panel;
Panel::Panel(glm::vec2 coord, glm::vec2 size, glm::vec4 color)
: coord(coord), size(size), color(color) {
}
void Panel::draw(Batch2D* batch) {
batch->texture(nullptr);
batch->color = color;
batch->rect(coord.x, coord.y, size.x, size.y);
}
bool Panel::isVisible() const {
return visible;
}
void Panel::setVisible(bool flag) {
visible = flag;
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef FRONTEND_GUI_PANEL_H_
#define FRONTEND_GUI_PANEL_H_
#include <glm/glm.hpp>
class Batch2D;
namespace gui {
class Panel {
glm::vec2 coord;
glm::vec2 size;
glm::vec4 color;
bool visible = true;
public:
Panel(glm::vec2 coord, glm::vec2 size, glm::vec4 color);
void draw(Batch2D* batch);
void setVisible(bool flag);
bool isVisible() const;
};
}
#endif // FRONTEND_GUI_PANEL_H_
+134
View File
@@ -0,0 +1,134 @@
#include "UINode.h"
#include "../../graphics/Batch2D.h"
using std::shared_ptr;
using gui::UINode;
using gui::Align;
using glm::vec2;
using glm::vec4;
#include <iostream>
UINode::UINode(vec2 coord, vec2 size) : coord(coord), size_(size) {
}
UINode::~UINode() {
}
bool UINode::visible() const {
return isvisible;
}
void UINode::visible(bool flag) {
isvisible = flag;
}
Align UINode::align() const {
return align_;
}
void UINode::align(Align align) {
align_ = align;
}
void UINode::hover(bool flag) {
hover_ = flag;
}
bool UINode::hover() const {
return hover_;
}
void UINode::setParent(UINode* node) {
parent = node;
}
UINode* UINode::getParent() const {
return parent;
}
void UINode::click(GUI*, int x, int y) {
pressed_ = true;
focused_ = true;
}
void UINode::mouseRelease(GUI*, int x, int y) {
pressed_ = false;
}
bool UINode::ispressed() const {
return pressed_;
}
void UINode::defocus() {
focused_ = false;
}
bool UINode::isfocused() const {
return focused_;
}
bool UINode::isInside(glm::vec2 pos) {
vec2 coord = calcCoord();
vec2 size = this->size();
return (pos.x >= coord.x && pos.y >= coord.y &&
pos.x < coord.x + size.x && pos.y < coord.y + size.y);
}
shared_ptr<UINode> UINode::getAt(vec2 pos, shared_ptr<UINode> self) {
return isInside(pos) ? self : nullptr;
}
vec2 UINode::calcCoord() const {
if (parent) {
return coord + parent->calcCoord();
}
return coord;
}
void UINode::setCoord(vec2 coord) {
this->coord = coord;
}
vec2 UINode::size() const {
return size_;
}
void UINode::size(vec2 size) {
if (sizelock)
return;
this->size_ = size;
if (parent) {
sizelock = true;
parent->refresh();
sizelock = false;
}
}
void UINode::_size(vec2 size) {
if (sizelock)
return;
this->size_ = size;
}
void UINode::color(vec4 color) {
this->color_ = color;
}
vec4 UINode::color() const {
return color_;
}
void UINode::margin(vec4 margin) {
this->margin_ = margin;
}
vec4 UINode::margin() const {
return margin_;
}
void UINode::lock() {
}
+82
View File
@@ -0,0 +1,82 @@
#ifndef FRONTEND_GUI_UINODE_H_
#define FRONTEND_GUI_UINODE_H_
#include <glm/glm.hpp>
#include <vector>
#include <memory>
#include <functional>
class Batch2D;
class Assets;
namespace gui {
class UINode;
class GUI;
typedef std::function<void(GUI*)> onaction;
typedef std::function<void(GUI*, double)> onnumberchange;
enum class Align {
left, center, right
};
class UINode {
protected:
glm::vec2 coord;
glm::vec2 size_;
glm::vec4 color_ {1.0f};
glm::vec4 margin_ {1.0f};
bool isvisible = true;
bool sizelock = false;
bool hover_ = false;
bool pressed_ = false;
bool focused_ = false;
Align align_ = Align::left;
UINode* parent = nullptr;
UINode(glm::vec2 coord, glm::vec2 size);
public:
virtual ~UINode();
virtual void draw(Batch2D* batch, Assets* assets) = 0;
virtual void visible(bool flag);
bool visible() const;
virtual void align(Align align);
Align align() const;
virtual void hover(bool flag);
bool hover() const;
virtual void setParent(UINode* node);
UINode* getParent() const;
virtual void color(glm::vec4 newColor);
glm::vec4 color() const;
virtual void margin(glm::vec4 margin);
glm::vec4 margin() const;
virtual void click(GUI*, int x, int y);
virtual void mouseRelease(GUI*, int x, int y);
bool ispressed() const;
void defocus();
bool isfocused() const;
virtual bool isfocuskeeper() const {return false;}
virtual void typed(unsigned int codepoint) {};
virtual void keyPressed(int key) {};
virtual bool isInside(glm::vec2 pos);
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self);
glm::vec2 calcCoord() const;
void setCoord(glm::vec2 coord);
glm::vec2 size() const;
virtual void size(glm::vec2 size);
void _size(glm::vec2 size);
virtual void refresh() {};
virtual void lock();
};
}
#endif // FRONTEND_GUI_UINODE_H_
+133
View File
@@ -0,0 +1,133 @@
#include "controls.h"
#include <iostream>
#include "../../assets/Assets.h"
#include "../../graphics/Batch2D.h"
#include "../../graphics/Font.h"
using std::string;
using std::wstring;
using std::shared_ptr;
using glm::vec2;
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
using namespace gui;
Label::Label(wstring text, string fontName)
: UINode(vec2(), vec2(text.length() * 8, 15)), text_(text), fontName_(fontName) {
}
Label& Label::text(wstring text) {
this->text_ = text;
return *this;
}
wstring Label::text() const {
return text_;
}
void Label::draw(Batch2D* batch, Assets* assets) {
if (supplier) {
text(supplier());
}
batch->color = color_;
Font* font = assets->getFont(fontName_);
vec2 size = this->size();
vec2 newsize = vec2(font->calcWidth(text_), font->lineHeight());
if (newsize.x > size.x) {
this->size(newsize);
size = newsize;
}
vec2 coord = calcCoord();
font->draw(batch, text_, coord.x, coord.y);
}
void Label::textSupplier(wstringsupplier supplier) {
this->supplier = supplier;
}
Button::Button(shared_ptr<UINode> content, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) {
add(content);
}
Button::Button(wstring text, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) {
Label* label = new Label(text);
label->align(Align::center);
add(shared_ptr<UINode>(label));
}
void Button::drawBackground(Batch2D* batch, Assets* assets) {
vec2 coord = calcCoord();
batch->texture(nullptr);
batch->color = (ispressed() ? pressedColor : (hover_ ? hoverColor : color_));
batch->rect(coord.x, coord.y, size_.x, size_.y);
}
shared_ptr<UINode> Button::getAt(vec2 pos, shared_ptr<UINode> self) {
return UINode::getAt(pos, self);
}
void Button::mouseRelease(GUI* gui, int x, int y) {
UINode::mouseRelease(gui, x, y);
if (isInside(vec2(x, y))) {
for (auto callback : actions) {
callback(gui);
}
}
}
void Button::listenAction(onaction action) {
actions.push_back(action);
}
TextBox::TextBox(wstring text, vec4 padding) : Panel(vec2(200,32), padding, 0, false) {
label = new Label(text);
label->align(Align::center);
add(shared_ptr<UINode>(label));
}
void TextBox::drawBackground(Batch2D* batch, Assets* assets) {
vec2 coord = calcCoord();
batch->texture(nullptr);
batch->color = (isfocused() ? focusedColor : (hover_ ? hoverColor : color_));
batch->rect(coord.x, coord.y, size_.x, size_.y);
if (!focused_ && supplier) {
label->text(supplier());
}
}
void TextBox::typed(unsigned int codepoint) {
label->text(label->text() + wstring({(wchar_t)codepoint}));
}
void TextBox::keyPressed(int key) {
wstring src = label->text();
switch (key) {
case KEY_BACKSPACE:
if (src.length())
label->text(src.substr(0, src.length()-1));
break;
case KEY_ENTER:
if (consumer) {
consumer(label->text());
}
defocus();
break;
}
}
shared_ptr<UINode> TextBox::getAt(vec2 pos, shared_ptr<UINode> self) {
return UINode::getAt(pos, self);
}
void TextBox::textSupplier(wstringsupplier supplier) {
this->supplier = supplier;
}
void TextBox::textConsumer(wstringconsumer consumer) {
this->consumer = consumer;
}
+72
View File
@@ -0,0 +1,72 @@
#ifndef FRONTEND_GUI_CONTROLS_H_
#define FRONTEND_GUI_CONTROLS_H_
#include <string>
#include <memory>
#include <vector>
#include <functional>
#include <glm/glm.hpp>
#include "UINode.h"
#include "panels.h"
class Batch2D;
class Assets;
namespace gui {
typedef std::function<std::wstring()> wstringsupplier;
typedef std::function<void(std::wstring)> wstringconsumer;
class Label : public UINode {
protected:
std::wstring text_;
std::string fontName_;
wstringsupplier supplier = nullptr;
public:
Label(std::wstring text, std::string fontName="normal");
virtual Label& text(std::wstring text);
std::wstring text() const;
virtual void draw(Batch2D* batch, Assets* assets);
virtual void textSupplier(wstringsupplier supplier);
};
class Button : public Panel {
protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f};
std::vector<onaction> actions;
public:
Button(std::shared_ptr<UINode> content, glm::vec4 padding=glm::vec4(2.0f));
Button(std::wstring text, glm::vec4 padding=glm::vec4(2.0f));
virtual void drawBackground(Batch2D* batch, Assets* assets);
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
virtual void mouseRelease(GUI*, int x, int y) override;
virtual void listenAction(onaction action);
};
class TextBox : public Panel {
protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
Label* label;
wstringsupplier supplier = nullptr;
wstringconsumer consumer = nullptr;
public:
TextBox(std::wstring text, glm::vec4 padding=glm::vec4(2.0f));
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
virtual void typed(unsigned int codepoint) override;
virtual void keyPressed(int key) override;
virtual void textSupplier(wstringsupplier supplier);
virtual void textConsumer(wstringconsumer consumer);
virtual bool isfocuskeeper() const override {return true;}
};
}
#endif // FRONTEND_GUI_CONTROLS_H_
+130
View File
@@ -0,0 +1,130 @@
#include "panels.h"
#include "../../window/Window.h"
#include "../../assets/Assets.h"
#include "../../graphics/Batch2D.h"
using std::shared_ptr;
using gui::UINode;
using gui::Container;
using gui::Panel;
using gui::Orientation;
using glm::vec2;
using glm::vec4;
Container::Container(vec2 coord, vec2 size) : UINode(coord, size) {
}
shared_ptr<UINode> Container::getAt(vec2 pos, shared_ptr<UINode> self) {
for (auto node : nodes) {
if (!node->visible())
continue;
auto hover = node->getAt(pos, node);
if (hover != nullptr) {
return hover;
}
}
return UINode::getAt(pos, self);
}
void Container::draw(Batch2D* batch, Assets* assets) {
vec2 coord = calcCoord();
vec2 size = this->size();
drawBackground(batch, assets);
batch->texture(nullptr);
batch->render();
Window::pushScissor(vec4(coord.x, coord.y, size.x, size.y));
for (auto node : nodes) {
if (node->visible())
node->draw(batch, assets);
}
batch->render();
Window::popScissor();
}
void Container::add(shared_ptr<UINode> node) {
nodes.push_back(node);
node->setParent(this);
refresh();
}
Panel::Panel(vec2 size, glm::vec4 padding, float interval, bool resizing)
: Container(vec2(), size), padding(padding), interval(interval), resizing_(resizing) {
color_ = vec4(0.0f, 0.0f, 0.0f, 0.75f);
}
Panel::~Panel() {
}
void Panel::drawBackground(Batch2D* batch, Assets* assets) {
vec2 coord = calcCoord();
batch->texture(nullptr);
batch->color = color_;
batch->rect(coord.x, coord.y, size_.x, size_.y);
}
void Panel::refresh() {
float x = padding.x;
float y = padding.y;
vec2 size = this->size();
if (orientation_ == Orientation::vertical) {
float maxw = size.x;
for (auto node : nodes) {
vec2 nodesize = node->size();
const vec4 margin = node->margin();
y += margin.y;
float ex;
switch (node->align()) {
case Align::center:
ex = x + fmax(0.0f, (size.x - margin.z - padding.z) - node->size().x) / 2.0f;
break;
case Align::right:
ex = x + size.x - margin.z - padding.z - node->size().x;
break;
default:
ex = x + margin.x;
}
node->setCoord(vec2(ex, y));
y += nodesize.y + margin.w + interval;
node->size(vec2(size.x - padding.x - padding.z - margin.x - margin.z, nodesize.y));
maxw = fmax(maxw, ex+node->size().x+margin.z+padding.z);
}
if (resizing_)
this->size(vec2(maxw, y+padding.w));
} else {
float maxh = size.y;
for (auto node : nodes) {
vec2 nodesize = node->size();
const vec4 margin = node->margin();
x += margin.x;
node->setCoord(vec2(x, y+margin.y));
x += nodesize.x + margin.z + interval;
node->size(vec2(nodesize.x, size.y - padding.y - padding.w - margin.y - margin.w));
maxh = fmax(maxh, y+margin.y+node->size().y+margin.w+padding.w);
}
bool increased = maxh > size.y;
if (resizing_)
this->size(vec2(x+padding.z, maxh));
if (increased)
refresh();
}
}
void Panel::orientation(Orientation orientation) {
this->orientation_ = orientation;
}
Orientation Panel::orientation() const {
return orientation_;
}
void Panel::lock(){
for (auto node : nodes) {
node->lock();
}
resizing_ = false;
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef FRONTEND_GUI_PANELS_H_
#define FRONTEND_GUI_PANELS_H_
#include <glm/glm.hpp>
#include <vector>
#include <memory>
#include "UINode.h"
class Batch2D;
class Assets;
namespace gui {
enum class Orientation { vertical, horizontal };
class Container : public UINode {
protected:
std::vector<std::shared_ptr<UINode>> nodes;
public:
Container(glm::vec2 coord, glm::vec2 size);
virtual void drawBackground(Batch2D* batch, Assets* assets) {};
virtual void draw(Batch2D* batch, Assets* assets);
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
virtual void add(std::shared_ptr<UINode> node);
};
class Panel : public Container {
protected:
Orientation orientation_ = Orientation::vertical;
glm::vec4 padding {2.0f};
float interval = 2.0f;
bool resizing_;
public:
Panel(glm::vec2 size, glm::vec4 padding=glm::vec4(2.0f), float interval=2.0f, bool resizing=true);
virtual ~Panel();
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
virtual void orientation(Orientation orientation);
Orientation orientation() const;
virtual void refresh() override;
virtual void lock() override;
};
}
#endif // FRONTEND_GUI_PANELS_H_