Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/graphics/core/Batch2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Texture.hpp"
#include "gl_util.hpp"
#include "maths/UVRegion.hpp"
#include <glm/glm.hpp>

#include <cmath>

Expand Down Expand Up @@ -342,6 +343,66 @@ void Batch2D::triangle(float x1, float y1, float x2, float y2, float x3, float y
vertex({x3, y3}, {x3, y3}, color.r, color.g, color.b, color.a);
}

void Batch2D::roundedRect(float x, float y, float w, float h, float radius, float borderWidth) {
if (radius <= 0.0f) {
if (borderWidth <= 0.0f) {
rect(x, y, w, h); // просто заполненный
} else {
// Нарисовать бордер как 4 линии
lineRect(x, y, w, h);
// Если borderWidth > 1, можно рисовать несколько слоёв
}
return;
}

int segments = 8; // количество треугольников на угол
float angleStep = HALF_PI / segments;

if (borderWidth <= 0.0f) {
// --- Заполненный прямоугольник с radius ---
rect(x + radius, y, w - 2*radius, h);
rect(x, y + radius, radius, h - 2*radius);
rect(x + w - radius, y + radius, radius, h - 2*radius);

for (int i = 0; i < segments; ++i) {
float theta0 = i * angleStep;
float theta1 = (i + 1) * angleStep;

// Верхний левый угол
triangle(x + radius, y + radius,
x + radius - radius * cos(theta0), y + radius - radius * sin(theta0),
x + radius - radius * cos(theta1), y + radius - radius * sin(theta1));

// Верхний правый угол
triangle(x + w - radius, y + radius,
x + w - radius + radius * cos(theta0), y + radius - radius * sin(theta0),
x + w - radius + radius * cos(theta1), y + radius - radius * sin(theta1));

// Нижний левый угол
triangle(x + radius, y + h - radius,
x + radius - radius * cos(theta0), y + h - radius + radius * sin(theta0),
x + radius - radius * cos(theta1), y + h - radius + radius * sin(theta1));

// Нижний правый угол
triangle(x + w - radius, y + h - radius,
x + w - radius + radius * cos(theta0), y + h - radius + radius * sin(theta0),
x + w - radius + radius * cos(theta1), y + h - radius + radius * sin(theta1));
}
} else {
// --- Нарисовать только бордер с толщиной ---
// Можно аппроксимировать как 4 полоски + дуги
// Верхняя полоса
roundedRect(x, y, w, borderWidth, radius);
// Нижняя полоса
roundedRect(x, y + h - borderWidth, w, borderWidth, radius);
// Левая полоса
roundedRect(x, y + borderWidth, borderWidth, h - 2*borderWidth, radius);
// Правая полоса
roundedRect(x + w - borderWidth, y + borderWidth, borderWidth, h - 2*borderWidth, radius);
}
}


void Batch2D::sprite(float x, float y, float w, float h, const UVRegion& region, glm::vec4 tint){
rect(x, y, w, h, region.u1, region.v1, region.u2-region.u1, region.v2-region.v1, tint.r, tint.g, tint.b, tint.a);
}
Expand Down
5 changes: 5 additions & 0 deletions src/graphics/core/Batch2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "maths/UVRegion.hpp"
#include "MeshData.hpp"

constexpr float PI = 3.14159265358979323846f;
constexpr float HALF_PI = PI / 2.0f;

template<typename VertexStructure>
class Mesh;
class Texture;
Expand Down Expand Up @@ -122,4 +125,6 @@ class Batch2D : public Flushable {
void flush() override;

void lineWidth(float width);

void roundedRect(float x, float y, float w, float h, float radius, float borderWidth = 0.0f);
};
114 changes: 53 additions & 61 deletions src/graphics/ui/GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,24 @@
#include "assets/Assets.hpp"
#include "elements/Label.hpp"
#include "elements/Menu.hpp"
#include "elements/Node.hpp"
#include "elements/Panel.hpp"
#include "elements/UINode.hpp"
#include "engine/Engine.hpp"
#include "frontend/UiDocument.hpp"
#include "frontend/locale.hpp"
#include "graphics/core/Batch2D.hpp"
#include "graphics/core/LineBatch.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/core/Font.hpp"
#include "graphics/core/DrawContext.hpp"
#include "graphics/core/Font.hpp"
#include "graphics/core/LineBatch.hpp"
#include "graphics/core/Shader.hpp"
#include "gui_util.hpp"
#include "style/StyleComputer.hpp"
#include "style/StylesheetParser.hpp"
#include "window/Camera.hpp"
#include "window/Window.hpp"
#include "window/input.hpp"

#include <algorithm>
#include <utility>

using namespace gui;

GUI::GUI(Engine& engine)
Expand All @@ -50,12 +49,58 @@ GUI::GUI(Engine& engine)
tooltip = guiutil::create(
*this,
"<container color='#000000A0' interactive='false' z-index='999'>"
"<label id='tooltip.label' markup='md' pos='2' autoresize='true' multiline='true' text-wrap='false'></label>"
"<label id='tooltip.label' markup='md' pos='2' autoresize='true' "
"multiline='true' text-wrap='false'></label>"
"</container>"
);
store("tooltip", tooltip);
store("tooltip.label", UINode::find(tooltip, "tooltip.label"));
container->add(tooltip);

// Testing new UI Implementation

std::string xmlString = R"(
<div class="main">
<span style = "background: #555;">
<text>Left</text>
</span>
<span style = "background: #555;">
<text>Right</text>
</span>
</div>
)";
std::string css_code = R"(
// comment variant 1
/* comment variant 2 */
div.main {
background: #111f;
align-x: center;
align-y: center;
}

span {
width: 100;
height: 100;
align-x: center;
align-y: center;

border-width: 1;
border-color: #ff0000;
border-radius: 15;
}

)";

document_root = Node::from_xml_string("example.xml", xmlString);

StylesheetParser parser("test.css", css_code);
style::Stylesheet stylesheet = parser.parse();

style::StyleComputer computer;
computer.set_inherit_exceptions({"width", "height", "margin", "padding", "direction", "align-x", "align-y", "border-width","border-color", "border-radius"});

computer.set_stylesheets({stylesheet});
computer.compute(*document_root);
}

GUI::~GUI() = default;
Expand Down Expand Up @@ -235,62 +280,9 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) {
auto ctx = pctx.sub(batch2D.get());

auto& viewport = ctx.getViewport();

auto& page = menu->getCurrent();
if (page.panel) {
menu->setSize(page.panel->getSize());
page.panel->refresh();
if (auto panel = std::dynamic_pointer_cast<gui::Panel>(page.panel)) {
panel->cropToContent();
}
}
menu->setPos((glm::vec2(viewport) - menu->getSize()) / 2.0f);
uicamera->setFov(viewport.y);
uicamera->setAspectRatio(viewport.x / static_cast<float>(viewport.y));

auto uishader = assets.get<Shader>("ui");
uishader->use();
uishader->uniformMatrix("u_projview", uicamera->getProjView());

batch2D->begin();
container->draw(ctx, assets);

if (hover) {
engine.getWindow().setCursor(hover->getCursor());
}
if (hover && debug) {
auto pos = hover->calcPos();
const auto& id = hover->getId();
if (!id.empty()) {
auto& font = assets.require<Font>(FONT_DEFAULT);
auto text = util::str2wstr_utf8(id);
int width = font.calcWidth(text);
int height = font.getLineHeight();

batch2D->untexture();
batch2D->setColor(0, 0, 0);
batch2D->rect(pos.x, pos.y, width, height);

batch2D->resetColor();
font.draw(*batch2D, text, pos.x, pos.y, nullptr, 0);
}

batch2D->untexture();
auto node = hover->getParent();
while (node) {
auto parentPos = node->calcPos();
auto size = node->getSize();

batch2D->setColor(0, 255, 255);
batch2D->lineRect(parentPos.x+1, parentPos.y, size.x-2, size.y-1);

node = node->getParent();
}
// debug draw
auto size = hover->getSize();
batch2D->setColor(0, 255, 0);
batch2D->lineRect(pos.x, pos.y, size.x-1, size.y-1);
}
document_root->draw(ctx, assets);
}

std::shared_ptr<UINode> GUI::getFocused() const {
Expand Down
3 changes: 3 additions & 0 deletions src/graphics/ui/GUI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>
#include <glm/glm.hpp>
#include <unordered_map>
#include "elements/Node.hpp"

class DrawContext;
class Assets;
Expand Down Expand Up @@ -84,6 +85,8 @@ namespace gui {
bool doubleClicked = false;
bool debug = false;

std::shared_ptr<Node> document_root = std::make_shared<Node>("div");;

void actMouse(float delta, const CursorState& cursor);
void actFocused();
void updateTooltip(float delta);
Expand Down
Loading