Refactor Shader uniform API + Added back NuakeUI
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -31,3 +31,9 @@
|
||||
[submodule "Nuake/dependencies/yoga"]
|
||||
path = Nuake/dependencies/yoga
|
||||
url = https://github.com/facebook/yoga.git
|
||||
[submodule "Nuake/dependencies/--force"]
|
||||
path = Nuake/dependencies/--force
|
||||
url = https://github.com/freetype/freetype.git
|
||||
[submodule "Nuake/dependencies/freetype"]
|
||||
path = Nuake/dependencies/freetype
|
||||
url = https://github.com/freetype/freetype.git
|
||||
|
||||
BIN
Editor/SourceSansPro-Regular.ttf
Normal file
BIN
Editor/SourceSansPro-Regular.ttf
Normal file
Binary file not shown.
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include "src/UI/NuakeUI.h"
|
||||
#include "src/UI/UIInputManager.h"
|
||||
|
||||
void EditorApplication::OnInit()
|
||||
{
|
||||
@@ -71,6 +73,16 @@ void EditorApplication::OnInit()
|
||||
}
|
||||
});
|
||||
|
||||
NuakeUI::CanvasParser parser;
|
||||
Ref<NuakeUI::Canvas> canvas = parser.Parse("test.html");
|
||||
|
||||
static MyInputManager inputManager(*m_Window);
|
||||
|
||||
canvas->SetInputManager(&inputManager);
|
||||
canvas->ComputeLayout({1920, 1080});
|
||||
canvas->Tick();
|
||||
canvas->Draw();
|
||||
|
||||
PushLayer(CreateScope<EditorLayer>());
|
||||
}
|
||||
|
||||
|
||||
@@ -189,10 +189,10 @@ void GizmoDrawer::DrawAxis(Ref<Scene> scene, bool occluded)
|
||||
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
|
||||
{
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform1f("u_Opacity", occluded ? 0.1f : 0.5f);
|
||||
m_LineShader->SetUniformVec4("u_Color", {0.0f, 0.0f, 0.0f, 0.0f});
|
||||
m_LineShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", occluded ? 0.1f : 0.5f);
|
||||
m_LineShader->SetUniform("u_Color", {0.0f, 0.0f, 0.0f, 0.0f});
|
||||
m_AxisLineBuffer->Bind();
|
||||
glLineWidth(1.0f);
|
||||
Nuake::RenderCommand::DrawLines(0, 6);
|
||||
@@ -234,9 +234,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, box.Size));
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, box.Size));
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_BoxBuffer->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 26);
|
||||
@@ -256,9 +256,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 0.9f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, volume.VolumeSize));
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 0.9f);
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix, volume.VolumeSize));
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_BoxBuffer->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 26);
|
||||
@@ -269,9 +269,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
{
|
||||
auto [transform, sphere] = scene->m_Registry.get<TransformComponent, SphereColliderComponent>(e);
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(sphere.Radius)));
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(sphere.Radius)));
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CircleBuffer->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 128);
|
||||
@@ -290,14 +290,14 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
|
||||
Vector3 globalPosition = Vector3(transform.GetGlobalTransform()[3]);
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MaxDistance)));
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MaxDistance)));
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CircleBuffer->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 128);
|
||||
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MinDistance)));
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), globalPosition), Vector3(emitter.MinDistance)));
|
||||
Nuake::RenderCommand::DrawLines(0, 128);
|
||||
}
|
||||
|
||||
@@ -318,9 +318,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CapsuleGizmo[entityId]->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 264);
|
||||
@@ -343,9 +343,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.0f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.0f);
|
||||
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CylinderGizmo[entityId]->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 264);
|
||||
@@ -376,9 +376,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
gizmoPosition = glm::translate(gizmoPosition, { 0, -cylinderLength / 2.0, 0 });
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.0f);
|
||||
m_LineShader->SetUniformMat4f("u_View", gizmoPosition);
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.0f);
|
||||
m_LineShader->SetUniform("u_View", gizmoPosition);
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CylinderGizmo[entityId]->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 264);
|
||||
@@ -419,9 +419,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
{
|
||||
auto [transform, particle] = scene->m_Registry.get<TransformComponent, ParticleEmitterComponent>(e);
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(particle.Radius)));
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_Opacity", 1.f);
|
||||
m_LineShader->SetUniform("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])), Vector3(particle.Radius)));
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
m_CircleBuffer->Bind();
|
||||
Nuake::RenderCommand::DrawLines(0, 128);
|
||||
@@ -450,8 +450,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniformMat4f("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
m_LineShader->SetUniform("u_View", glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix);
|
||||
m_LineShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
meshes[mesh.SubMesh]->Bind();
|
||||
@@ -461,9 +461,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
|
||||
auto flatShader = ShaderManager::GetShader("Resources/Shaders/flat.shader");
|
||||
flatShader->Bind();
|
||||
flatShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
|
||||
flatShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
flatShader->SetUniform4f("u_Color", 0.5f, 0.5f, 0.5f, 1.0f);
|
||||
flatShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
|
||||
flatShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
flatShader->SetUniform("u_Color", 0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
|
||||
RenderCommand::Enable(RendererEnum::FACE_CULL);
|
||||
@@ -474,9 +474,9 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
|
||||
auto gizmoShader = ShaderManager::GetShader("Resources/Shaders/gizmo.shader");
|
||||
gizmoShader->Bind();
|
||||
gizmoShader->SetUniformMat4f("u_View", scene->m_EditorCamera->GetTransform());
|
||||
gizmoShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
gizmoShader->SetUniform1f("u_Opacity", occluded ? 0.1f : 1.f);
|
||||
gizmoShader->SetUniform("u_View", scene->m_EditorCamera->GetTransform());
|
||||
gizmoShader->SetUniform("u_Projection", scene->m_EditorCamera->GetPerspective());
|
||||
gizmoShader->SetUniform("u_Opacity", occluded ? 0.1f : 1.f);
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
|
||||
const Vector3& cameraPosition = scene->m_EditorCamera->GetTranslation();
|
||||
@@ -487,8 +487,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
|
||||
for (auto e : camView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/camera.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/camera.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transform, camera] = scene->m_Registry.get<TransformComponent, CameraComponent>(e);
|
||||
|
||||
auto initialTransform = transform.GetGlobalTransform();
|
||||
@@ -527,8 +527,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
texturePath = "Resources/Gizmos/light.png";
|
||||
}
|
||||
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture(texturePath).get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture(texturePath).get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
|
||||
auto initialTransform = transform.GetGlobalTransform();
|
||||
Matrix4 particleTransform = initialTransform;
|
||||
@@ -548,8 +548,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto characterControllerView = scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
||||
for (auto e : characterControllerView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/player.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/player.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transform, characterControllerComponent] = scene->m_Registry.get<TransformComponent, CharacterControllerComponent>(e);
|
||||
|
||||
auto initialTransform = transform.GetGlobalTransform();
|
||||
@@ -571,8 +571,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto boneView = scene->m_Registry.view<TransformComponent, BoneComponent>();
|
||||
for (auto e : boneView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/bone.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/bone.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transform, boneComponent] = scene->m_Registry.get<TransformComponent, BoneComponent>(e);
|
||||
|
||||
auto initialTransform = transform.GetGlobalTransform();
|
||||
@@ -593,8 +593,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto audioView = scene->m_Registry.view<TransformComponent, AudioEmitterComponent>();
|
||||
for (auto e : audioView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/sound_emitter.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/sound_emitter.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transformComponent, audioEmitterComponent] = scene->m_Registry.get<TransformComponent, AudioEmitterComponent>(e);
|
||||
|
||||
auto initialTransform = transformComponent.GetGlobalTransform();
|
||||
@@ -614,8 +614,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto rigidbodyView = scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
for (auto e : rigidbodyView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/rigidbody.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/rigidbody.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transformComponent, rigidbodyComponent] = scene->m_Registry.get<TransformComponent, RigidBodyComponent>(e);
|
||||
|
||||
auto initialTransform = transformComponent.GetGlobalTransform();
|
||||
@@ -635,8 +635,8 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
auto particleEmitterView = scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
|
||||
for (auto e : particleEmitterView)
|
||||
{
|
||||
gizmoShader->SetUniformTex("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/particles.png").get());
|
||||
gizmoShader->SetUniform1i("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
gizmoShader->SetUniform("gizmo_texture", TextureManager::Get()->GetTexture("Resources/Gizmos/particles.png").get());
|
||||
gizmoShader->SetUniform("u_EntityID", ((int32_t)(uint32_t)(e)) + 1);
|
||||
auto [transformComponent, particleEmitter] = scene->m_Registry.get<TransformComponent, ParticleEmitterComponent>(e);
|
||||
|
||||
auto initialTransform = transformComponent.GetGlobalTransform();
|
||||
|
||||
@@ -127,9 +127,9 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
// shader->Bind();
|
||||
//
|
||||
// auto cam = Engine::GetCurrentScene()->GetCurrentCamera();
|
||||
// shader->SetUniformMat4f("u_View", view);
|
||||
// shader->SetUniformMat4f("u_Projection", ortho);
|
||||
// shader->SetUniformMat4f("u_Model", Matrix4(1.0f));
|
||||
// shader->SetUniform("u_View", view);
|
||||
// shader->SetUniform("u_Projection", ortho);
|
||||
// shader->SetUniform("u_Model", Matrix4(1.0f));
|
||||
// Renderer::SphereMesh->Draw(shader, true);
|
||||
//}
|
||||
//m_Framebuffer->Unbind();
|
||||
@@ -143,15 +143,15 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
// RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
// auto shader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
|
||||
// shader->Bind();
|
||||
// shader->SetUniformVec3("u_EyePosition", Vector3(1, 0, 0));
|
||||
// shader->SetUniform1i("LightCount", 0);
|
||||
// shader->SetUniform("u_EyePosition", Vector3(1, 0, 0));
|
||||
// shader->SetUniform("LightCount", 0);
|
||||
// auto dir = Engine::GetCurrentScene()->GetEnvironment()->ProceduralSkybox->GetSunDirection();
|
||||
// shader->SetUniform3f("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
|
||||
// shader->SetUniform3f("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
|
||||
// shader->SetUniform1i("u_DirectionalLight.Shadow", 0);
|
||||
// shader->SetUniform1i("u_DisableSSAO", 1);
|
||||
// shader->SetUniformMat4f("u_View", view);
|
||||
// shader->SetUniformMat4f("u_Projection", ortho);
|
||||
// shader->SetUniform("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
|
||||
// shader->SetUniform("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
|
||||
// shader->SetUniform("u_DirectionalLight.Shadow", 0);
|
||||
// shader->SetUniform("u_DisableSSAO", 1);
|
||||
// shader->SetUniform("u_View", view);
|
||||
// shader->SetUniform("u_Projection", ortho);
|
||||
//
|
||||
// m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
|
||||
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->Bind(6);
|
||||
@@ -159,11 +159,11 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8);
|
||||
// m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT4)->Bind(10);
|
||||
//
|
||||
// shader->SetUniform1i("m_Depth", 5);
|
||||
// shader->SetUniform1i("m_Albedo", 6);
|
||||
// shader->SetUniform1i("m_Normal", 7);
|
||||
// shader->SetUniform1i("m_Material", 8);
|
||||
// shader->SetUniform1i("m_Emissive", 10);
|
||||
// shader->SetUniform("m_Depth", 5);
|
||||
// shader->SetUniform("m_Albedo", 6);
|
||||
// shader->SetUniform("m_Normal", 7);
|
||||
// shader->SetUniform("m_Material", 8);
|
||||
// shader->SetUniform("m_Emissive", 10);
|
||||
//
|
||||
// Renderer::DrawQuad(Matrix4());
|
||||
//}
|
||||
@@ -215,9 +215,9 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
shader->Bind();
|
||||
|
||||
auto cam = Engine::GetCurrentScene()->GetCurrentCamera();
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniformMat4f("u_Projection", ortho);
|
||||
shader->SetUniformMat4f("u_Model", Matrix4(1.0f));
|
||||
shader->SetUniform("u_View", view);
|
||||
shader->SetUniform("u_Projection", ortho);
|
||||
shader->SetUniform("u_Model", Matrix4(1.0f));
|
||||
Ref<Material> material = ResourceLoader::LoadMaterial(path);
|
||||
material->Bind(shader);
|
||||
Renderer::SphereMesh->Draw(shader, false);
|
||||
@@ -233,15 +233,15 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
auto shader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
|
||||
shader->Bind();
|
||||
shader->SetUniformVec3("u_EyePosition", Vector3(1, 0, 0));
|
||||
shader->SetUniform1i("LightCount", 0);
|
||||
shader->SetUniform("u_EyePosition", Vector3(1, 0, 0));
|
||||
shader->SetUniform("LightCount", 0);
|
||||
auto dir = Engine::GetCurrentScene()->GetEnvironment()->ProceduralSkybox->GetSunDirection();
|
||||
shader->SetUniform3f("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
|
||||
shader->SetUniform3f("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
|
||||
shader->SetUniform1i("u_DirectionalLight.Shadow", 0);
|
||||
shader->SetUniform1i("u_DisableSSAO", 1);
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniformMat4f("u_Projection", ortho);
|
||||
shader->SetUniform("u_DirectionalLight.Direction", 0.6, -0.6, 0.6);
|
||||
shader->SetUniform("u_DirectionalLight.Color", 10.0f, 10.0f, 10.0f);
|
||||
shader->SetUniform("u_DirectionalLight.Shadow", 0);
|
||||
shader->SetUniform("u_DisableSSAO", 1);
|
||||
shader->SetUniform("u_View", view);
|
||||
shader->SetUniform("u_Projection", ortho);
|
||||
|
||||
m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
|
||||
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->Bind(6);
|
||||
@@ -249,11 +249,11 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
|
||||
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8);
|
||||
m_Framebuffer->GetTexture(GL_COLOR_ATTACHMENT4)->Bind(10);
|
||||
|
||||
shader->SetUniform1i("m_Depth", 5);
|
||||
shader->SetUniform1i("m_Albedo", 6);
|
||||
shader->SetUniform1i("m_Normal", 7);
|
||||
shader->SetUniform1i("m_Material", 8);
|
||||
shader->SetUniform1i("m_Emissive", 10);
|
||||
shader->SetUniform("m_Depth", 5);
|
||||
shader->SetUniform("m_Albedo", 6);
|
||||
shader->SetUniform("m_Normal", 7);
|
||||
shader->SetUniform("m_Material", 8);
|
||||
shader->SetUniform("m_Emissive", 10);
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
}
|
||||
|
||||
5
Editor/test.html
Normal file
5
Editor/test.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<div class="main">
|
||||
<p>Hello</p>
|
||||
</div>
|
||||
</div>
|
||||
1
Nuake/dependencies/freetype
Submodule
1
Nuake/dependencies/freetype
Submodule
Submodule Nuake/dependencies/freetype added at ba47af32ba
84
Nuake/dependencies/freetype_p5.lua
Normal file
84
Nuake/dependencies/freetype_p5.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
group "Dependencies"
|
||||
project "Freetype"
|
||||
location "freetype"
|
||||
kind "StaticLib"
|
||||
staticruntime "on"
|
||||
language "C"
|
||||
|
||||
targetdir ("freetype/bin/" .. outputdir .. "/%{prj.name}")
|
||||
objdir ("freetype/bin-obj/" .. outputdir .. "/%{prj.name}")
|
||||
|
||||
includedirs {
|
||||
'freetype/include/',
|
||||
'freetype/',
|
||||
"freetype/include/config/"
|
||||
}
|
||||
defines { "FT2_BUILD_LIBRARY" }
|
||||
|
||||
files {
|
||||
"freetype/src/autofit/autofit.c",
|
||||
"freetype/src/base/ftbase.c",
|
||||
"freetype/src/base/ftbbox.c",
|
||||
"freetype/src/base/ftbdf.c",
|
||||
"freetype/src/base/ftbitmap.c",
|
||||
"freetype/src/base/ftcid.c",
|
||||
"freetype/src/base/ftfstype.c",
|
||||
"freetype/src/base/ftgasp.c",
|
||||
"freetype/src/base/ftglyph.c",
|
||||
"freetype/src/base/ftgxval.c",
|
||||
"freetype/src/base/ftinit.c",
|
||||
"freetype/src/base/ftmm.c",
|
||||
"freetype/src/base/ftotval.c",
|
||||
"freetype/src/base/ftpatent.c",
|
||||
"freetype/src/base/ftpfr.c",
|
||||
"freetype/src/base/ftstroke.c",
|
||||
"freetype/src/base/ftsynth.c",
|
||||
"freetype/src/base/ftsystem.c",
|
||||
"freetype/src/base/fttype1.c",
|
||||
"freetype/src/base/ftwinfnt.c",
|
||||
"freetype/src/bdf/bdf.c",
|
||||
"freetype/src/cache/ftcache.c",
|
||||
"freetype/src/cff/cff.c",
|
||||
"freetype/src/cid/type1cid.c",
|
||||
"freetype/src/gzip/ftgzip.c",
|
||||
"freetype/src/lzw/ftlzw.c",
|
||||
"freetype/src/pcf/pcf.c",
|
||||
"freetype/src/pfr/pfr.c",
|
||||
"freetype/src/psaux/psaux.c",
|
||||
"freetype/src/pshinter/pshinter.c",
|
||||
"freetype/src/psnames/psmodule.c",
|
||||
"freetype/src/raster/raster.c",
|
||||
"freetype/src/sfnt/sfnt.c",
|
||||
"freetype/src/smooth/smooth.c",
|
||||
"freetype/src/truetype/truetype.c",
|
||||
"freetype/src/type1/type1.c",
|
||||
"freetype/src/type42/type42.c",
|
||||
"freetype/src/winfonts/winfnt.c",
|
||||
"freetype/src/winfonts/winfnt.c",
|
||||
"freetype/src/sdf/sdf.c"
|
||||
}
|
||||
|
||||
|
||||
filter "system:windows"
|
||||
systemversion "latest"
|
||||
|
||||
defines
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
filter "configurations:Debug"
|
||||
files { "freetype/src/base/ftdebug.c" }
|
||||
runtime "Debug"
|
||||
symbols "on"
|
||||
|
||||
filter "configurations:Release"
|
||||
files { "freetype/src/base/ftdebug.c" }
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
|
||||
filter "configurations:Dist"
|
||||
files { "freetype/src/base/ftdebug.c" }
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
group ""
|
||||
79
Nuake/dependencies/msdf-atlas-gen_p5.lua
Normal file
79
Nuake/dependencies/msdf-atlas-gen_p5.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
project '*'
|
||||
includedirs {
|
||||
'yoga/yoga/'
|
||||
}
|
||||
|
||||
group "Dependencies"
|
||||
|
||||
project 'msdf-gen'
|
||||
kind "StaticLib"
|
||||
staticruntime "on"
|
||||
warnings 'Off'
|
||||
optimize 'Speed'
|
||||
cppdialect "C++20"
|
||||
|
||||
includedirs {
|
||||
'msdf-atlas-gen/include',
|
||||
'freetype/include'
|
||||
}
|
||||
|
||||
files {
|
||||
'msdf-atlas-gen/msdfgen/*.h',
|
||||
'msdf-atlas-gen/msdfgen/*.cpp',
|
||||
'msdf-atlas-gen/msdfgen/*.hpp',
|
||||
'msdf-atlas-gen/msdfgen/Core/*.h',
|
||||
'msdf-atlas-gen/msdfgen/Core/*.hpp',
|
||||
'msdf-atlas-gen/msdfgen/Core/*.cpp',
|
||||
'msdf-atlas-gen/msdfgen/lib/*.cpp',
|
||||
'msdf-atlas-gen/msdfgen/ext/*.h',
|
||||
'msdf-atlas-gen/msdfgen/ext/*.cpp'
|
||||
}
|
||||
|
||||
defines {
|
||||
|
||||
}
|
||||
|
||||
filter "configurations:Debug"
|
||||
runtime "Debug"
|
||||
symbols "on"
|
||||
|
||||
filter "configurations:Release"
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
|
||||
project 'msdf-atlas-gen'
|
||||
kind "StaticLib"
|
||||
staticruntime "on"
|
||||
warnings 'Off'
|
||||
optimize 'Speed'
|
||||
cppdialect "C++20"
|
||||
|
||||
includedirs {
|
||||
'msdf-atlas-gen/include',
|
||||
'msdf-atlas-gen/msdfgen',
|
||||
'msdf-atlas-gen/msdfgen/include'
|
||||
}
|
||||
|
||||
files {
|
||||
'msdf-atlas-gen/msdf-atlas-gen/*.h',
|
||||
'msdf-atlas-gen/msdf-atlas-gen/*.cpp',
|
||||
'msdf-atlas-gen/msdf-atlas-gen/*.hpp',
|
||||
}
|
||||
|
||||
links {
|
||||
'msdf-gen'
|
||||
}
|
||||
|
||||
defines {
|
||||
|
||||
}
|
||||
|
||||
filter "configurations:Debug"
|
||||
runtime "Debug"
|
||||
symbols "on"
|
||||
|
||||
filter "configurations:Release"
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
|
||||
group ""
|
||||
@@ -18,6 +18,8 @@ project 'yoga'
|
||||
files {
|
||||
'yoga/yoga/*.cpp',
|
||||
'yoga/yoga/*.h',
|
||||
'yoga/yoga/**/*.cpp',
|
||||
'yoga/yoga/**/*.h',
|
||||
}
|
||||
|
||||
defines {
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Nuake
|
||||
void Mesh::DebugDraw()
|
||||
{
|
||||
Renderer::m_DebugShader->Bind();
|
||||
Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
Renderer::m_DebugShader->SetUniform("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
|
||||
m_VertexArray->Bind();
|
||||
RenderCommand::DrawElements(RendererEnum::TRIANGLES, m_IndicesCount, RendererEnum::UINT, 0);
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace Nuake
|
||||
void SkinnedMesh::DebugDraw()
|
||||
{
|
||||
Renderer::m_DebugShader->Bind();
|
||||
Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
Renderer::m_DebugShader->SetUniform("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
|
||||
m_VertexArray->Bind();
|
||||
RenderCommand::DrawElements(RendererEnum::TRIANGLES, (int)m_Indices.size(), RendererEnum::UINT, 0);
|
||||
|
||||
@@ -78,10 +78,10 @@ namespace Nuake
|
||||
{
|
||||
m_ThresholdFB->Clear();
|
||||
shader->Bind();
|
||||
shader->SetUniform1i("u_Stage", 0);
|
||||
shader->SetUniform1f("u_Threshold", m_Threshold);
|
||||
shader->SetUniform("u_Stage", 0);
|
||||
shader->SetUniform("u_Threshold", m_Threshold);
|
||||
m_Source->Bind(1);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform("u_Source", 1);
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
}
|
||||
@@ -91,13 +91,13 @@ namespace Nuake
|
||||
m_DownSampleFB[i]->Bind();
|
||||
m_DownSampleFB[i]->Clear();
|
||||
|
||||
shader->SetUniform1i("u_Stage", 1);
|
||||
shader->SetUniform("u_Stage", 1);
|
||||
|
||||
Ref<Texture> downsampleTexture = i == 0 ? m_ThresholdFB->GetTexture() : m_DownSampleFB[i - 1]->GetTexture();
|
||||
shader->SetUniformTex("u_Source", downsampleTexture.get(), 1);
|
||||
shader->SetUniform("u_Source", downsampleTexture.get(), 1);
|
||||
|
||||
Vector2 size = i == 0 ? downsampleTexture->GetSize() : m_DownSampleFB[i]->GetTexture()->GetSize();
|
||||
shader->SetUniformVec2("u_SourceSize", size);
|
||||
shader->SetUniform("u_SourceSize", size);
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
m_DownSampleFB[i]->Unbind();
|
||||
@@ -109,13 +109,13 @@ namespace Nuake
|
||||
m_HBlurFB[i]->Bind();
|
||||
m_HBlurFB[i]->Clear();
|
||||
|
||||
shader->SetUniform1i("u_Stage", 2);
|
||||
shader->SetUniform2f("u_BlurDirection", 0.0f, 1.0f);
|
||||
shader->SetUniform("u_Stage", 2);
|
||||
shader->SetUniform("u_BlurDirection", 0.0f, 1.0f);
|
||||
|
||||
Ref<Texture> blurTexture = m_DownSampleFB[m_Iteration - i - 1]->GetTexture();
|
||||
blurTexture->Bind(1);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform2f("u_SourceSize", (float)blurTexture->GetWidth(), (float)blurTexture->GetHeight());
|
||||
shader->SetUniform("u_Source", 1);
|
||||
shader->SetUniform("u_SourceSize", (float)blurTexture->GetWidth(), (float)blurTexture->GetHeight());
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
m_HBlurFB[i]->Unbind();
|
||||
@@ -124,12 +124,12 @@ namespace Nuake
|
||||
m_VBlurFB[i]->Bind();
|
||||
m_VBlurFB[i]->Clear();
|
||||
|
||||
shader->SetUniform1i("u_Stage", 2);
|
||||
shader->SetUniform2f("u_BlurDirection", 1.0f, 0.0f);
|
||||
shader->SetUniform("u_Stage", 2);
|
||||
shader->SetUniform("u_BlurDirection", 1.0f, 0.0f);
|
||||
|
||||
m_HBlurFB[i]->GetTexture()->Bind(1);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform2f("u_SourceSize", (float)m_HBlurFB[i]->GetTexture()->GetWidth(), (float)m_HBlurFB[i]->GetTexture()->GetHeight());
|
||||
shader->SetUniform("u_Source", 1);
|
||||
shader->SetUniform("u_SourceSize", (float)m_HBlurFB[i]->GetTexture()->GetWidth(), (float)m_HBlurFB[i]->GetTexture()->GetHeight());
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
m_VBlurFB[i]->Unbind();
|
||||
@@ -140,20 +140,20 @@ namespace Nuake
|
||||
m_UpSampleFB[i]->Clear();
|
||||
if (i == 0)
|
||||
{
|
||||
shader->SetUniform1i("u_Stage", 3);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform("u_Stage", 3);
|
||||
shader->SetUniform("u_Source", 1);
|
||||
m_VBlurFB[i]->GetTexture()->Bind(1);
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
shader->SetUniform1i("u_Stage", 4);
|
||||
shader->SetUniform("u_Stage", 4);
|
||||
|
||||
m_VBlurFB[i]->GetTexture()->Bind(1);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform("u_Source", 1);
|
||||
|
||||
m_UpSampleFB[i - 1]->GetTexture()->Bind(2);
|
||||
shader->SetUniform1i("u_Source2", 2);
|
||||
shader->SetUniform2f("u_Source2Size", (float)m_UpSampleFB[i]->GetTexture()->GetWidth(), (float)m_UpSampleFB[i]->GetTexture()->GetHeight());
|
||||
shader->SetUniform("u_Source2", 2);
|
||||
shader->SetUniform("u_Source2Size", (float)m_UpSampleFB[i]->GetTexture()->GetWidth(), (float)m_UpSampleFB[i]->GetTexture()->GetHeight());
|
||||
}
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
m_UpSampleFB[i]->Unbind();
|
||||
@@ -161,9 +161,9 @@ namespace Nuake
|
||||
m_FinalFB->Bind();
|
||||
m_FinalFB->Clear();
|
||||
{
|
||||
shader->SetUniform1i("u_Stage", 5);
|
||||
shader->SetUniform1i("u_Source", 1);
|
||||
shader->SetUniform1i("u_Source2", 2);
|
||||
shader->SetUniform("u_Stage", 5);
|
||||
shader->SetUniform("u_Source", 1);
|
||||
shader->SetUniform("u_Source2", 2);
|
||||
m_UpSampleFB[m_Iteration - 1]->GetTexture()->Bind(1);
|
||||
m_Source->Bind(2);
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
|
||||
@@ -110,28 +110,28 @@ namespace Nuake
|
||||
const auto& normalTexture = gBuffer->GetTexture(GL_COLOR_ATTACHMENT1);
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/ssao.shader");
|
||||
shader->Bind();
|
||||
shader->SetUniformMat4f("u_Projection", projection);
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniformTex("u_Depth", depthTexture.get(), 2);
|
||||
shader->SetUniformTex("u_Normal", normalTexture.get(), 3);
|
||||
shader->SetUniformTex("u_Noise", _ssaoNoiseTexture.get(), 6);
|
||||
shader->SetUniform1i("u_KernelSize", 64);
|
||||
shader->SetUniform1f("u_Radius", Radius);
|
||||
shader->SetUniform1f("u_Bias", Bias);
|
||||
shader->SetUniform1f("u_Falloff", Falloff);
|
||||
shader->SetUniform1f("u_Area", Area);
|
||||
shader->SetUniform1f("u_Strength", Strength);
|
||||
shader->SetUniformVec2("u_NoiseScale", Vector2(_size.x / 4, _size.y / 4) );
|
||||
shader->SetUniform("u_Projection", projection);
|
||||
shader->SetUniform("u_View", view);
|
||||
shader->SetUniform("u_Depth", depthTexture.get(), 2);
|
||||
shader->SetUniform("u_Normal", normalTexture.get(), 3);
|
||||
shader->SetUniform("u_Noise", _ssaoNoiseTexture.get(), 6);
|
||||
shader->SetUniform("u_KernelSize", 64);
|
||||
shader->SetUniform("u_Radius", Radius);
|
||||
shader->SetUniform("u_Bias", Bias);
|
||||
shader->SetUniform("u_Falloff", Falloff);
|
||||
shader->SetUniform("u_Area", Area);
|
||||
shader->SetUniform("u_Strength", Strength);
|
||||
shader->SetUniform("u_NoiseScale", Vector2(_size.x / 4, _size.y / 4) );
|
||||
|
||||
int i = 0;
|
||||
for (const auto& k : _ssaoKernel)
|
||||
{
|
||||
const std::string& uniformName = "u_Samples[" + std::to_string(i) + "]";
|
||||
shader->SetUniform3f(uniformName, k.x, k.y, k.z);
|
||||
shader->SetUniform(uniformName, k.x, k.y, k.z);
|
||||
i++;
|
||||
}
|
||||
|
||||
//shader->SetUniform1fv("u_Samples", 64 * 3, (float*)&(_ssaoKernel.begin()));
|
||||
//shader->SetUniformv("u_Samples", 64 * 3, (float*)&(_ssaoKernel.begin()));
|
||||
Renderer::DrawQuad(Matrix4(1.0));
|
||||
}
|
||||
_ssaoFramebuffer->Unbind();
|
||||
@@ -141,7 +141,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/blur.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Input", _ssaoFramebuffer->GetTexture().get(), 2);
|
||||
shader->SetUniform("u_Input", _ssaoFramebuffer->GetTexture().get(), 2);
|
||||
|
||||
Renderer::DrawQuad(Matrix4(1.0));
|
||||
}
|
||||
|
||||
@@ -35,28 +35,28 @@ namespace Nuake {
|
||||
|
||||
mShader->Bind();
|
||||
|
||||
mShader->SetUniform1f("rayStep", RayStep);
|
||||
mShader->SetUniform1i("iterationCount", IterationCount);
|
||||
mShader->SetUniform1f("distanceBias", DistanceBias);
|
||||
mShader->SetUniform1i("enableSSR", (int)1);
|
||||
mShader->SetUniform1i("sampleCount", SampleCount);
|
||||
mShader->SetUniform1i("isSamplingEnabled", SamplingEnabled);
|
||||
mShader->SetUniform1i("isExponentialStepEnabled", ExpoStep);
|
||||
mShader->SetUniform1i("isAdaptiveStepEnabled", AdaptiveStep);
|
||||
mShader->SetUniform1i("isBinarySearchEnabled", BinarySearch);
|
||||
mShader->SetUniform1i("debugDraw", DebugDraw);
|
||||
mShader->SetUniform1f("samplingCoefficient", SampleingCoefficient);
|
||||
mShader->SetUniformMat4f("view", view);
|
||||
mShader->SetUniformMat4f("invView", glm::inverse(view));
|
||||
mShader->SetUniformMat4f("proj", projection);
|
||||
mShader->SetUniformMat4f("invProj", glm::inverse(projection));
|
||||
mShader->SetUniform("rayStep", RayStep);
|
||||
mShader->SetUniform("iterationCount", IterationCount);
|
||||
mShader->SetUniform("distanceBias", DistanceBias);
|
||||
mShader->SetUniform("enableSSR", (int)1);
|
||||
mShader->SetUniform("sampleCount", SampleCount);
|
||||
mShader->SetUniform("isSamplingEnabled", SamplingEnabled);
|
||||
mShader->SetUniform("isExponentialStepEnabled", ExpoStep);
|
||||
mShader->SetUniform("isAdaptiveStepEnabled", AdaptiveStep);
|
||||
mShader->SetUniform("isBinarySearchEnabled", BinarySearch);
|
||||
mShader->SetUniform("debugDraw", DebugDraw);
|
||||
mShader->SetUniform("samplingCoefficient", SampleingCoefficient);
|
||||
mShader->SetUniform("view", view);
|
||||
mShader->SetUniform("invView", glm::inverse(view));
|
||||
mShader->SetUniform("proj", projection);
|
||||
mShader->SetUniform("invProj", glm::inverse(projection));
|
||||
|
||||
mShader->SetUniformTex("textureDepth", gBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get(), 1);
|
||||
mShader->SetUniformTex("textureNorm", gBuffer->GetTexture(GL_COLOR_ATTACHMENT1).get(), 2);
|
||||
mShader->SetUniformTex("textureMetallic", gBuffer->GetTexture(GL_COLOR_ATTACHMENT2).get(), 3);
|
||||
mShader->SetUniform("textureDepth", gBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get(), 1);
|
||||
mShader->SetUniform("textureNorm", gBuffer->GetTexture(GL_COLOR_ATTACHMENT1).get(), 2);
|
||||
mShader->SetUniform("textureMetallic", gBuffer->GetTexture(GL_COLOR_ATTACHMENT2).get(), 3);
|
||||
|
||||
mShader->SetUniformTex("textureAlbedo", gBuffer->GetTexture(GL_COLOR_ATTACHMENT0).get(), 5);
|
||||
mShader->SetUniformTex("textureFrame", previousFrame.get(), 7);
|
||||
mShader->SetUniform("textureAlbedo", gBuffer->GetTexture(GL_COLOR_ATTACHMENT0).get(), 5);
|
||||
mShader->SetUniform("textureFrame", previousFrame.get(), 7);
|
||||
|
||||
Renderer::DrawQuad(Matrix4());
|
||||
}
|
||||
|
||||
@@ -48,25 +48,25 @@ namespace Nuake {
|
||||
auto cameraPosition = Vector3(view[3]);
|
||||
Shader* volumetricShader = ShaderManager::GetShader("Resources/Shaders/volumetric.shader");
|
||||
volumetricShader->Bind();
|
||||
volumetricShader->SetUniformMat4f("u_Projection", projection);
|
||||
volumetricShader->SetUniformMat4f("u_View", view);
|
||||
volumetricShader->SetUniformTex("u_Depth", mDepth, 1);
|
||||
volumetricShader->SetUniformVec3("u_CamPosition", camPos);
|
||||
volumetricShader->SetUniform1i("u_StepCount", mStepCount);
|
||||
volumetricShader->SetUniform1f("u_FogAmount", mFogAmount);
|
||||
volumetricShader->SetUniform1i("u_LightCount", static_cast<int>(lights.size()));
|
||||
volumetricShader->SetUniform1f("u_Exponant", mFogExponant);
|
||||
volumetricShader->SetUniform("u_Projection", projection);
|
||||
volumetricShader->SetUniform("u_View", view);
|
||||
volumetricShader->SetUniform("u_Depth", mDepth, 1);
|
||||
volumetricShader->SetUniform("u_CamPosition", camPos);
|
||||
volumetricShader->SetUniform("u_StepCount", mStepCount);
|
||||
volumetricShader->SetUniform("u_FogAmount", mFogAmount);
|
||||
volumetricShader->SetUniform("u_LightCount", static_cast<int>(lights.size()));
|
||||
volumetricShader->SetUniform("u_Exponant", mFogExponant);
|
||||
for (uint16_t i = 0; i < lights.size(); i++)
|
||||
{
|
||||
LightComponent& light = lights[i];
|
||||
|
||||
std::string u_light = "u_Lights[" + std::to_string(i) + "].";
|
||||
volumetricShader->SetUniformMat4f(u_light + "transform", light.mViewProjections[0]);
|
||||
volumetricShader->SetUniformVec3(u_light + "color", light.Color);
|
||||
volumetricShader->SetUniformVec3(u_light + "direction", light.GetDirection());
|
||||
volumetricShader->SetUniform(u_light + "transform", light.mViewProjections[0]);
|
||||
volumetricShader->SetUniform(u_light + "color", light.Color);
|
||||
volumetricShader->SetUniform(u_light + "direction", light.GetDirection());
|
||||
|
||||
volumetricShader->SetUniformTex(u_light + "shadowmap", light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT).get(), 5 + i);
|
||||
volumetricShader->SetUniform1f(u_light + "strength", light.Strength);
|
||||
volumetricShader->SetUniform(u_light + "shadowmap", light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT).get(), 5 + i);
|
||||
volumetricShader->SetUniform(u_light + "strength", light.Strength);
|
||||
}
|
||||
|
||||
Renderer::DrawQuad();
|
||||
@@ -79,8 +79,8 @@ namespace Nuake {
|
||||
mFinalFramebuffer->Clear();
|
||||
Shader* blurShader = ShaderManager::GetShader("Resources/Shaders/blur.shader");
|
||||
blurShader->Bind();
|
||||
//blurShader->SetUniformTex("u_Depth", mDepth, 1);
|
||||
blurShader->SetUniformTex("u_Input", mVolumetricFramebuffer->GetTexture().get());
|
||||
//blurShader->SetUniform("u_Depth", mDepth, 1);
|
||||
blurShader->SetUniform("u_Input", mVolumetricFramebuffer->GetTexture().get());
|
||||
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
|
||||
@@ -58,10 +58,10 @@ namespace Nuake
|
||||
{
|
||||
if (!depthOnly)
|
||||
{
|
||||
shader->SetUniform1i(entityIdUniformLocation, m.entityId + 1);
|
||||
shader->SetUniform(entityIdUniformLocation, m.entityId + 1);
|
||||
}
|
||||
|
||||
shader->SetUniformMat4f(modelMatrixUniformLocation, m.transform);
|
||||
shader->SetUniform(modelMatrixUniformLocation, m.transform);
|
||||
m.mesh->Draw(shader, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,13 +243,13 @@ namespace Nuake
|
||||
{
|
||||
Shader* lineShader = ShaderManager::GetShader("Resources/Shaders/line.shader");
|
||||
lineShader->Bind();
|
||||
lineShader->SetUniformMat4f("u_Projection", camera->GetPerspective());
|
||||
lineShader->SetUniformMat4f("u_View", camera->GetTransform());
|
||||
lineShader->SetUniform("u_Projection", camera->GetPerspective());
|
||||
lineShader->SetUniform("u_View", camera->GetTransform());
|
||||
|
||||
m_Shader->Bind();
|
||||
m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective());
|
||||
m_Shader->SetUniformMat4f("u_View", camera->GetTransform());
|
||||
m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z);
|
||||
m_Shader->SetUniform("u_Projection", camera->GetPerspective());
|
||||
m_Shader->SetUniform("u_View", camera->GetTransform());
|
||||
m_Shader->SetUniform("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z);
|
||||
}
|
||||
|
||||
int spotShadowMapCount = 0;
|
||||
@@ -259,21 +259,21 @@ namespace Nuake
|
||||
|
||||
Shader* deferredShader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
|
||||
deferredShader->Bind();
|
||||
deferredShader->SetUniform1i("LightCount", 0);
|
||||
deferredShader->SetUniform("LightCount", 0);
|
||||
|
||||
for (int i = 0; i < m_Lights.size(); i++)
|
||||
{
|
||||
const std::string uniformAccessor = "Lights[" + std::to_string(i) + "].";
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Position", 0, 0, 0);
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Color", 0, 0, 0);
|
||||
deferredShader->SetUniform1i(uniformAccessor + "Type", -1);
|
||||
deferredShader->SetUniform1i(uniformAccessor + "CastShadow", 0);
|
||||
deferredShader->SetUniform1i(uniformAccessor + "ShadowMapID", -1);
|
||||
deferredShader->SetUniform(uniformAccessor + "Position", 0, 0, 0);
|
||||
deferredShader->SetUniform(uniformAccessor + "Color", 0, 0, 0);
|
||||
deferredShader->SetUniform(uniformAccessor + "Type", -1);
|
||||
deferredShader->SetUniform(uniformAccessor + "CastShadow", 0);
|
||||
deferredShader->SetUniform(uniformAccessor + "ShadowMapID", -1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
deferredShader->SetUniform1i("SpotShadowMaps[" + std::to_string(i) + "]", 0);
|
||||
deferredShader->SetUniform("SpotShadowMaps[" + std::to_string(i) + "]", 0);
|
||||
}
|
||||
|
||||
m_Lights.clear();
|
||||
@@ -297,7 +297,7 @@ namespace Nuake
|
||||
{
|
||||
int shadowmapAmount = 0;
|
||||
|
||||
deferredShader->SetUniform1i("u_DirectionalLight.Shadow", light.CastShadows);
|
||||
deferredShader->SetUniform("u_DirectionalLight.Shadow", light.CastShadows);
|
||||
|
||||
if (light.CastShadows)
|
||||
{
|
||||
@@ -305,16 +305,16 @@ namespace Nuake
|
||||
{
|
||||
light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17 + i);
|
||||
const uint32_t shadowMapId = shadowmapAmount + i;
|
||||
deferredShader->SetUniform1i("ShadowMaps[" + std::to_string(shadowMapId) + "]", 17 + i);
|
||||
deferredShader->SetUniform1i("u_DirectionalLight.ShadowMapsIDs[" + std::to_string(i) + "]", shadowMapId);
|
||||
deferredShader->SetUniform1f("u_DirectionalLight.CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]);
|
||||
deferredShader->SetUniformMat4f("u_DirectionalLight.LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]);
|
||||
deferredShader->SetUniform("ShadowMaps[" + std::to_string(shadowMapId) + "]", 17 + i);
|
||||
deferredShader->SetUniform("u_DirectionalLight.ShadowMapsIDs[" + std::to_string(i) + "]", shadowMapId);
|
||||
deferredShader->SetUniform("u_DirectionalLight.CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]);
|
||||
deferredShader->SetUniform("u_DirectionalLight.LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]);
|
||||
}
|
||||
}
|
||||
|
||||
deferredShader->SetUniform3f("u_DirectionalLight.Direction", direction.x, direction.y, direction.z);
|
||||
deferredShader->SetUniform1i("u_DirectionalLight.Volumetric", light.IsVolumetric);
|
||||
deferredShader->SetUniform3f("u_DirectionalLight.Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
deferredShader->SetUniform("u_DirectionalLight.Direction", direction.x, direction.y, direction.z);
|
||||
deferredShader->SetUniform("u_DirectionalLight.Volumetric", light.IsVolumetric);
|
||||
deferredShader->SetUniform("u_DirectionalLight.Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
|
||||
shadowmapAmount += CSM_AMOUNT;
|
||||
}
|
||||
@@ -329,38 +329,38 @@ namespace Nuake
|
||||
size_t idx = m_Lights.size();
|
||||
|
||||
const std::string uniformAccessor = "Lights[" + std::to_string(idx - 1) + "].";
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Position", pos.x, pos.y, pos.z);
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
deferredShader->SetUniform1i(uniformAccessor + "Type", static_cast<int>(light.Type));
|
||||
deferredShader->SetUniform1i(uniformAccessor + "CastShadow", static_cast<int>(light.CastShadows));
|
||||
deferredShader->SetUniform(uniformAccessor + "Position", pos.x, pos.y, pos.z);
|
||||
deferredShader->SetUniform(uniformAccessor + "Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
deferredShader->SetUniform(uniformAccessor + "Type", static_cast<int>(light.Type));
|
||||
deferredShader->SetUniform(uniformAccessor + "CastShadow", static_cast<int>(light.CastShadows));
|
||||
|
||||
if (light.Type == Spot)
|
||||
{
|
||||
direction = transform.GetGlobalRotation() * Vector3(0, 0, -1);
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Direction", direction.x, direction.y, direction.z);
|
||||
deferredShader->SetUniform1f(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
|
||||
deferredShader->SetUniform1f(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
|
||||
deferredShader->SetUniform(uniformAccessor + "Direction", direction.x, direction.y, direction.z);
|
||||
deferredShader->SetUniform(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
|
||||
deferredShader->SetUniform(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
|
||||
|
||||
if (light.CastShadows && spotShadowMapCount < MaxSpotShadowMap)
|
||||
{
|
||||
int shadowMapTextureSlot = 21 + spotShadowMapCount;
|
||||
deferredShader->SetUniform1i(uniformAccessor + "ShadowMapID", spotShadowMapCount);
|
||||
deferredShader->SetUniformMat4f(uniformAccessor + "Transform", light.GetProjection() * glm::inverse(transform.GetGlobalTransform()));
|
||||
deferredShader->SetUniform(uniformAccessor + "ShadowMapID", spotShadowMapCount);
|
||||
deferredShader->SetUniform(uniformAccessor + "Transform", light.GetProjection() * glm::inverse(transform.GetGlobalTransform()));
|
||||
|
||||
light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(shadowMapTextureSlot);
|
||||
deferredShader->SetUniform1i("SpotShadowMaps[" + std::to_string(spotShadowMapCount) + "]", shadowMapTextureSlot);
|
||||
deferredShader->SetUniform("SpotShadowMaps[" + std::to_string(spotShadowMapCount) + "]", shadowMapTextureSlot);
|
||||
spotShadowMapCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deferredShader->SetUniform3f(uniformAccessor + "Direction", 0, 0, 0);
|
||||
deferredShader->SetUniform1f(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
|
||||
deferredShader->SetUniform1f(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
|
||||
deferredShader->SetUniform1f(uniformAccessor + "ShadowMapID", -1);
|
||||
deferredShader->SetUniform(uniformAccessor + "Direction", 0, 0, 0);
|
||||
deferredShader->SetUniform(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
|
||||
deferredShader->SetUniform(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
|
||||
deferredShader->SetUniform(uniformAccessor + "ShadowMapID", -1);
|
||||
}
|
||||
|
||||
deferredShader->SetUniform1i("LightCount", static_cast<int>(idx));
|
||||
deferredShader->SetUniform("LightCount", static_cast<int>(idx));
|
||||
}
|
||||
|
||||
m_LightsUniformBuffer->Bind();
|
||||
@@ -370,8 +370,8 @@ namespace Nuake
|
||||
{
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/line.shader");
|
||||
shader->Bind();
|
||||
shader->SetUniformMat4f("u_Model", transform);
|
||||
shader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
shader->SetUniform("u_Model", transform);
|
||||
shader->SetUniform("u_Color", color.r, color.g, color.b, color.a);
|
||||
|
||||
std::vector<Vertex> vertices
|
||||
{
|
||||
@@ -394,14 +394,14 @@ namespace Nuake
|
||||
{
|
||||
|
||||
//m_DebugShader->Bind();
|
||||
//m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
//m_DebugShader->SetUniform("u_Color", color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void Renderer::DrawCube(TransformComponent transform, glm::vec4 color)
|
||||
{
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
m_DebugShader->SetUniformMat4f("u_Model", transform.GetGlobalTransform());
|
||||
m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
m_DebugShader->SetUniform("u_Model", transform.GetGlobalTransform());
|
||||
m_DebugShader->SetUniform("u_Color", color.r, color.g, color.b, color.a);
|
||||
|
||||
CubeMesh->Bind();
|
||||
RenderCommand::DrawArrays(0, 36);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Nuake
|
||||
glDisable(GL_CULL_FACE);
|
||||
Projection = glm::ortho(0.f, size.x, size.y, 0.f, -1.f, 1000.0f);
|
||||
UIShader->Bind();
|
||||
UIShader->SetUniformMat4f("projection", Projection);
|
||||
UIShader->SetUniform("projection", Projection);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawRect()
|
||||
@@ -69,9 +69,9 @@ namespace Nuake
|
||||
glm::decompose(transform, scale, rotation, translation, skew, perspective);
|
||||
|
||||
BeginDraw({ 1920.0f, 1080.0f });
|
||||
UIShader->SetUniformMat4f("model", transform);
|
||||
UIShader->SetUniform1f("u_border_radius", borderRadius);
|
||||
UIShader->SetUniform2f("u_size", scale.x, scale.y);
|
||||
UIShader->SetUniform("model", transform);
|
||||
UIShader->SetUniform("u_border_radius", borderRadius);
|
||||
UIShader->SetUniform("u_size", scale.x, scale.y);
|
||||
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
@@ -83,10 +83,10 @@ namespace Nuake
|
||||
model = glm::translate(model, Vector3(position.x, position.y, 0.f));
|
||||
model = glm::scale(model, Vector3(size.x, size.y, 1.f));
|
||||
|
||||
UIShader->SetUniformMat4f("model", model);
|
||||
UIShader->SetUniform1f("u_BorderRadius", borderRadius);
|
||||
UIShader->SetUniform2f("u_Size", size.x, size.y);
|
||||
UIShader->SetUniform4f("u_BackgroundColor", color.r, color.g, color.b, color.a);
|
||||
UIShader->SetUniform("model", model);
|
||||
UIShader->SetUniform("u_BorderRadius", borderRadius);
|
||||
UIShader->SetUniform("u_Size", size.x, size.y);
|
||||
UIShader->SetUniform("u_BackgroundColor", color.r, color.g, color.b, color.a);
|
||||
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
@@ -156,6 +156,13 @@ namespace Nuake
|
||||
mShadingBuffer->QueueResize(framebufferResolution);
|
||||
ShadingPass(scene);
|
||||
|
||||
ImGui::SetNextWindowSize({ 1280, 720 });
|
||||
if (ImGui::Begin("Shaded"))
|
||||
{
|
||||
ImGui::Image((void*)(mShadingBuffer->GetTexture()->GetID()), ImGui::GetContentRegionAvail(), { 0, 1 }, { 1, 0 });
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// Blit depth buffer
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mGBuffer->GetRenderID());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShadingBuffer->GetRenderID());
|
||||
@@ -176,7 +183,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mShadingBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source", mShadingBuffer->GetTexture().get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -217,8 +224,8 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/combine.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", finalOutput.get(), 0);
|
||||
shader->SetUniformTex("u_Source2", sceneEnv->mVolumetric->GetFinalOutput().get(), 1);
|
||||
shader->SetUniform("u_Source", finalOutput.get(), 0);
|
||||
shader->SetUniform("u_Source2", sceneEnv->mVolumetric->GetFinalOutput().get(), 1);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -231,7 +238,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", finalOutput.get(), 0);
|
||||
shader->SetUniform("u_Source", finalOutput.get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
}
|
||||
@@ -246,9 +253,9 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/tonemap.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniform1f("u_Exposure", sceneEnv->Exposure);
|
||||
shader->SetUniform1f("u_Gamma", sceneEnv->Gamma);
|
||||
shader->SetUniformTex("u_Source", finalOutput.get());
|
||||
shader->SetUniform("u_Exposure", sceneEnv->Exposure);
|
||||
shader->SetUniform("u_Gamma", sceneEnv->Gamma);
|
||||
shader->SetUniform("u_Source", finalOutput.get());
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
mToneMapBuffer->Unbind();
|
||||
@@ -262,11 +269,11 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/outline.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniform1i("u_EntityID", mOutlineEntityID == -1 ? -1 : mOutlineEntityID + 1);
|
||||
shader->SetUniformTex("u_EntityTexture", mGBuffer->GetTexture(GL_COLOR_ATTACHMENT3).get(), 0);
|
||||
shader->SetUniformVec4("u_OutlineColor", projectSettings.PrimaryColor);
|
||||
shader->SetUniformTex("u_Depth", mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT), 1);
|
||||
shader->SetUniform1f("u_Radius", projectSettings.OutlineRadius * projectSettings.ResolutionScale);
|
||||
shader->SetUniform("u_EntityID", mOutlineEntityID == -1 ? -1 : mOutlineEntityID + 1);
|
||||
shader->SetUniform("u_EntityTexture", mGBuffer->GetTexture(GL_COLOR_ATTACHMENT3).get(), 0);
|
||||
shader->SetUniform("u_OutlineColor", projectSettings.PrimaryColor);
|
||||
shader->SetUniform("u_Depth", mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get(), 1);
|
||||
shader->SetUniform("u_Radius", projectSettings.OutlineRadius * projectSettings.ResolutionScale);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
mOutlineBuffer->Unbind();
|
||||
@@ -277,8 +284,8 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/add.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniformTex("u_Source2", mOutlineBuffer->GetTexture().get(), 1);
|
||||
shader->SetUniform("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source2", mOutlineBuffer->GetTexture().get(), 1);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -289,7 +296,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", framebuffer.GetTexture().get(), 1);
|
||||
shader->SetUniform("u_Source", framebuffer.GetTexture().get(), 1);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
mToneMapBuffer->Unbind();
|
||||
@@ -305,8 +312,8 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/combine.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniformTex("u_Source2", sceneEnv->mSSR->OutputFramebuffer->GetTexture().get(), 1);
|
||||
shader->SetUniform("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source2", sceneEnv->mSSR->OutputFramebuffer->GetTexture().get(), 1);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -319,7 +326,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source", mToneMapBuffer->GetTexture().get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -332,32 +339,32 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/dof.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniform1f("focalDepth", sceneEnv->DOFFocalDepth);
|
||||
shader->SetUniform1f("focalLength", sceneEnv->DOFFocalLength);
|
||||
shader->SetUniform1f("fstop", sceneEnv->DOFFstop);
|
||||
shader->SetUniform1i("showFocus", sceneEnv->DOFShowFocus);
|
||||
shader->SetUniform1i("autofocus", sceneEnv->DOFAutoFocus);
|
||||
shader->SetUniform1i("samples", sceneEnv->DOFSamples);
|
||||
shader->SetUniform1i("manualdof", sceneEnv->DOFManualFocus);
|
||||
shader->SetUniform1f("rings", static_cast<float>(sceneEnv->DOFrings));
|
||||
shader->SetUniform1f("ndofstart", sceneEnv->DOFStart);
|
||||
shader->SetUniform1f("ndofdist", sceneEnv->DOFDist);
|
||||
shader->SetUniform1f("fdofstart", sceneEnv->DOFStart);
|
||||
shader->SetUniform1f("fdofdist", sceneEnv->DOFDist);
|
||||
shader->SetUniform1f("CoC", sceneEnv->DOFCoc);
|
||||
shader->SetUniform1f("maxblur", sceneEnv->DOFMaxBlue);
|
||||
shader->SetUniform1f("threshold", sceneEnv->DOFThreshold);
|
||||
shader->SetUniform1f("gain", sceneEnv->DOFGain);
|
||||
shader->SetUniform1f("bias", sceneEnv->DOFBias);
|
||||
shader->SetUniform1f("fringe", sceneEnv->DOFFringe);
|
||||
shader->SetUniform1f("namount", sceneEnv->DOFNAmmount);
|
||||
shader->SetUniform1f("dbsize", sceneEnv->DOFDbSize);
|
||||
shader->SetUniform1f("feather", sceneEnv->DOFFeather);
|
||||
shader->SetUniform1f("u_Distortion", sceneEnv->BarrelDistortion);
|
||||
shader->SetUniform1f("height", static_cast<float>(finalOutput->GetHeight()));
|
||||
shader->SetUniform1f("width", static_cast<float>(finalOutput->GetWidth()));
|
||||
shader->SetUniformTex("depthTex", mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get(), 0);
|
||||
shader->SetUniformTex("renderTex", finalOutput.get(), 1);
|
||||
shader->SetUniform("focalDepth", sceneEnv->DOFFocalDepth);
|
||||
shader->SetUniform("focalLength", sceneEnv->DOFFocalLength);
|
||||
shader->SetUniform("fstop", sceneEnv->DOFFstop);
|
||||
shader->SetUniform("showFocus", sceneEnv->DOFShowFocus);
|
||||
shader->SetUniform("autofocus", sceneEnv->DOFAutoFocus);
|
||||
shader->SetUniform("samples", sceneEnv->DOFSamples);
|
||||
shader->SetUniform("manualdof", sceneEnv->DOFManualFocus);
|
||||
shader->SetUniform("rings", static_cast<float>(sceneEnv->DOFrings));
|
||||
shader->SetUniform("ndofstart", sceneEnv->DOFStart);
|
||||
shader->SetUniform("ndofdist", sceneEnv->DOFDist);
|
||||
shader->SetUniform("fdofstart", sceneEnv->DOFStart);
|
||||
shader->SetUniform("fdofdist", sceneEnv->DOFDist);
|
||||
shader->SetUniform("CoC", sceneEnv->DOFCoc);
|
||||
shader->SetUniform("maxblur", sceneEnv->DOFMaxBlue);
|
||||
shader->SetUniform("threshold", sceneEnv->DOFThreshold);
|
||||
shader->SetUniform("gain", sceneEnv->DOFGain);
|
||||
shader->SetUniform("bias", sceneEnv->DOFBias);
|
||||
shader->SetUniform("fringe", sceneEnv->DOFFringe);
|
||||
shader->SetUniform("namount", sceneEnv->DOFNAmmount);
|
||||
shader->SetUniform("dbsize", sceneEnv->DOFDbSize);
|
||||
shader->SetUniform("feather", sceneEnv->DOFFeather);
|
||||
shader->SetUniform("u_Distortion", sceneEnv->BarrelDistortion);
|
||||
shader->SetUniform("height", static_cast<float>(finalOutput->GetHeight()));
|
||||
shader->SetUniform("width", static_cast<float>(finalOutput->GetWidth()));
|
||||
shader->SetUniform("depthTex", mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get(), 0);
|
||||
shader->SetUniform("renderTex", finalOutput.get(), 1);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
mDOFBuffer->Unbind();
|
||||
@@ -369,17 +376,17 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/barrel_distortion.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniform1f("u_Distortion", sceneEnv->BarrelDistortion);
|
||||
shader->SetUniform1f("u_DistortionEdge", sceneEnv->BarrelEdgeDistortion);
|
||||
shader->SetUniform1f("u_Scale", sceneEnv->BarrelScale);
|
||||
shader->SetUniform("u_Distortion", sceneEnv->BarrelDistortion);
|
||||
shader->SetUniform("u_DistortionEdge", sceneEnv->BarrelEdgeDistortion);
|
||||
shader->SetUniform("u_Scale", sceneEnv->BarrelScale);
|
||||
|
||||
if (sceneEnv->DOFEnabled)
|
||||
{
|
||||
shader->SetUniformTex("u_Source", mDOFBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source", mDOFBuffer->GetTexture().get(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->SetUniformTex("u_Source", finalOutput.get(), 0);
|
||||
shader->SetUniform("u_Source", finalOutput.get(), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -393,7 +400,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mBarrelDistortionBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source", mBarrelDistortionBuffer->GetTexture().get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -405,9 +412,9 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/vignette.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniform1f("u_Intensity", sceneEnv->VignetteIntensity);
|
||||
shader->SetUniform1f("u_Extend", sceneEnv->VignetteEnabled ? sceneEnv->VignetteExtend : 0.0f);
|
||||
shader->SetUniformTex("u_Source", framebuffer.GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Intensity", sceneEnv->VignetteIntensity);
|
||||
shader->SetUniform("u_Extend", sceneEnv->VignetteEnabled ? sceneEnv->VignetteExtend : 0.0f);
|
||||
shader->SetUniform("u_Source", framebuffer.GetTexture().get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
mVignetteBuffer->Unbind();
|
||||
@@ -418,8 +425,8 @@ namespace Nuake
|
||||
// Shader* shader = ShaderManager::GetShader("Resources/Shaders/add.shader");
|
||||
// shader->Bind();
|
||||
//
|
||||
// shader->SetUniformTex("u_Source", mVignetteBuffer->GetTexture().get(), 0);
|
||||
// shader->SetUniformTex("u_Source2", mOutlineBuffer->GetTexture().get(), 1);
|
||||
// shader->SetUniform("u_Source", mVignetteBuffer->GetTexture().get(), 0);
|
||||
// shader->SetUniform("u_Source2", mOutlineBuffer->GetTexture().get(), 1);
|
||||
// Renderer::DrawQuad();
|
||||
//}
|
||||
//framebuffer.Unbind();
|
||||
@@ -430,7 +437,7 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/copy.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformTex("u_Source", mVignetteBuffer->GetTexture().get(), 0);
|
||||
shader->SetUniform("u_Source", mVignetteBuffer->GetTexture().get(), 0);
|
||||
Renderer::DrawQuad();
|
||||
}
|
||||
framebuffer.Unbind();
|
||||
@@ -449,9 +456,9 @@ namespace Nuake
|
||||
// Shader* shader = ShaderManager::GetShader("Resources/Shaders/vignette.shader");
|
||||
// shader->Bind();
|
||||
//
|
||||
// shader->SetUniform1f("u_Intensity", sceneEnv->VignetteIntensity);
|
||||
// shader->SetUniform1f("u_Extend", sceneEnv->VignetteExtend);
|
||||
// shader->SetUniformTex("u_Source", mBarrelDistortionBuffer->GetTexture().get(), 0);
|
||||
// shader->SetUniform("u_Intensity", sceneEnv->VignetteIntensity);
|
||||
// shader->SetUniform("u_Extend", sceneEnv->VignetteExtend);
|
||||
// shader->SetUniform("u_Source", mBarrelDistortionBuffer->GetTexture().get(), 0);
|
||||
// Renderer::DrawQuad();
|
||||
//}
|
||||
//mVignetteBuffer->Unbind();
|
||||
@@ -535,7 +542,7 @@ namespace Nuake
|
||||
light.m_Framebuffers[i]->Bind();
|
||||
light.m_Framebuffers[i]->Clear();
|
||||
{
|
||||
shader->SetUniformMat4f("u_LightTransform", light.mViewProjections[i]);
|
||||
shader->SetUniform("u_LightTransform", light.mViewProjections[i]);
|
||||
for (auto e : meshView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = meshView.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
|
||||
@@ -627,7 +634,7 @@ namespace Nuake
|
||||
const Quat& globalRotation = glm::normalize(lightTransform.GetGlobalRotation());
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
shader->SetUniformMat4f("u_LightTransform", light.GetProjection() * glm::inverse(lightTransform.GetGlobalTransform()));
|
||||
shader->SetUniform("u_LightTransform", light.GetProjection() * glm::inverse(lightTransform.GetGlobalTransform()));
|
||||
for (auto e : meshView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = meshView.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
|
||||
@@ -701,7 +708,7 @@ namespace Nuake
|
||||
Shader* gBufferSkinnedMeshShader = ShaderManager::GetShader("Resources/Shaders/shadowMap_skinned.shader");
|
||||
gBufferSkinnedMeshShader->Bind();
|
||||
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
gBufferSkinnedMeshShader->SetUniform(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
|
||||
auto skinnedView = scene.m_Registry.view<TransformComponent, SkinnedModelComponent, VisibilityComponent>();
|
||||
for (auto l : view)
|
||||
@@ -716,7 +723,7 @@ namespace Nuake
|
||||
{
|
||||
light.m_Framebuffers[i]->Bind();
|
||||
{
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_LightTransform", light.mViewProjections[i]);
|
||||
gBufferSkinnedMeshShader->SetUniform("u_LightTransform", light.mViewProjections[i]);
|
||||
for (auto e : skinnedView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = skinnedView.get<TransformComponent, SkinnedModelComponent, VisibilityComponent>(e);
|
||||
@@ -743,7 +750,7 @@ namespace Nuake
|
||||
displayDepthShader->Bind();
|
||||
|
||||
GetGBuffer().GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
|
||||
displayDepthShader->SetUniform1i("u_Source", 5);
|
||||
displayDepthShader->SetUniform("u_Source", 5);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::DEPTH_TEST);
|
||||
Renderer::DrawQuad(Matrix4(1.0f));
|
||||
@@ -766,8 +773,8 @@ namespace Nuake
|
||||
Shader* gBufferSkinnedMeshShader = ShaderManager::GetShader("Resources/Shaders/gbuffer_skinned.shader");
|
||||
|
||||
gBufferShader->Bind();
|
||||
gBufferShader->SetUniformMat4f("u_Projection", mProjection);
|
||||
gBufferShader->SetUniformMat4f("u_View", mView);
|
||||
gBufferShader->SetUniform("u_Projection", mProjection);
|
||||
gBufferShader->SetUniform("u_View", mView);
|
||||
|
||||
// Models
|
||||
auto view = scene.m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
|
||||
@@ -923,15 +930,15 @@ namespace Nuake
|
||||
|
||||
// Skinned mesh at the end because we switch shader
|
||||
gBufferSkinnedMeshShader->Bind();
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_Projection", mProjection);
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_View", mView);
|
||||
gBufferSkinnedMeshShader->SetUniform("u_Projection", mProjection);
|
||||
gBufferSkinnedMeshShader->SetUniform("u_View", mView);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
|
||||
// Skinned Models
|
||||
const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID");
|
||||
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
gBufferSkinnedMeshShader->SetUniform(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
auto skinnedModelView = scene.m_Registry.view<TransformComponent, SkinnedModelComponent, VisibilityComponent>();
|
||||
for (auto e : skinnedModelView)
|
||||
{
|
||||
@@ -947,7 +954,7 @@ namespace Nuake
|
||||
{
|
||||
m->GetMaterial()->Bind(gBufferSkinnedMeshShader);
|
||||
|
||||
gBufferSkinnedMeshShader->SetUniform1i(entityIdUniformLocation, (uint32_t)e + 1);
|
||||
gBufferSkinnedMeshShader->SetUniform(entityIdUniformLocation, (uint32_t)e + 1);
|
||||
m->Draw(gBufferSkinnedMeshShader, true);
|
||||
}
|
||||
}
|
||||
@@ -984,11 +991,11 @@ namespace Nuake
|
||||
|
||||
Shader* shadingShader = ShaderManager::GetShader("Resources/Shaders/deferred.shader");
|
||||
shadingShader->Bind();
|
||||
shadingShader->SetUniformMat4f("u_Projection", mProjection);
|
||||
shadingShader->SetUniformMat4f("u_View", mView);
|
||||
shadingShader->SetUniformVec3("u_EyePosition", scene.GetCurrentCamera()->Translation);
|
||||
shadingShader->SetUniform1f("u_AmbientTerm", environment->AmbientTerm);
|
||||
shadingShader->SetUniformTex("m_SSAO", scene.GetEnvironment()->mSSAO->GetOuput()->GetTexture().get(), 9);
|
||||
shadingShader->SetUniform("u_Projection", mProjection);
|
||||
shadingShader->SetUniform("u_View", mView);
|
||||
shadingShader->SetUniform("u_EyePosition", scene.GetCurrentCamera()->Translation);
|
||||
shadingShader->SetUniform("u_AmbientTerm", environment->AmbientTerm);
|
||||
shadingShader->SetUniform("m_SSAO", scene.GetEnvironment()->mSSAO->GetOuput()->GetTexture().get(), 9);
|
||||
|
||||
Ref<Environment> env = scene.GetEnvironment();
|
||||
|
||||
@@ -1045,11 +1052,11 @@ namespace Nuake
|
||||
mGBuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8);
|
||||
mGBuffer->GetTexture(GL_COLOR_ATTACHMENT4)->Bind(10);
|
||||
|
||||
shadingShader->SetUniform1i("m_Depth", 5);
|
||||
shadingShader->SetUniform1i("m_Albedo", 6);
|
||||
shadingShader->SetUniform1i("m_Normal", 7);
|
||||
shadingShader->SetUniform1i("m_Material", 8);
|
||||
shadingShader->SetUniform1i("m_Emissive", 10);
|
||||
shadingShader->SetUniform("m_Depth", 5);
|
||||
shadingShader->SetUniform("m_Albedo", 6);
|
||||
shadingShader->SetUniform("m_Normal", 7);
|
||||
shadingShader->SetUniform("m_Material", 8);
|
||||
shadingShader->SetUniform("m_Emissive", 10);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
|
||||
@@ -1073,15 +1080,15 @@ namespace Nuake
|
||||
Shader* shader = ShaderManager::GetShader("Resources/Shaders/debugLine.shader");
|
||||
shader->Bind();
|
||||
|
||||
shader->SetUniformMat4f("u_Projection", mProjection);
|
||||
shader->SetUniformMat4f("u_View", mView);
|
||||
shader->SetUniform("u_Projection", mProjection);
|
||||
shader->SetUniform("u_View", mView);
|
||||
|
||||
bool depthTestState = true;
|
||||
for (auto& l : mDebugLines)
|
||||
{
|
||||
shader->SetUniformVec4("u_Color", l.LineColor);
|
||||
shader->SetUniformVec3("u_StartPos", l.Start);
|
||||
shader->SetUniformVec3("u_EndPos", l.End);
|
||||
shader->SetUniform("u_Color", l.LineColor);
|
||||
shader->SetUniform("u_StartPos", l.Start);
|
||||
shader->SetUniform("u_EndPos", l.End);
|
||||
|
||||
if (l.DepthTest)
|
||||
{
|
||||
@@ -1096,8 +1103,8 @@ namespace Nuake
|
||||
|
||||
shader = Nuake::ShaderManager::GetShader("Resources/Shaders/line.shader");
|
||||
shader->Bind();
|
||||
shader->SetUniform1f("u_Opacity", 0.5f);
|
||||
shader->SetUniformMat4f("u_Projection", mProjection);
|
||||
shader->SetUniform("u_Opacity", 0.5f);
|
||||
shader->SetUniform("u_Projection", mProjection);
|
||||
|
||||
for (auto& shape : mDebugShapes)
|
||||
{
|
||||
@@ -1110,7 +1117,7 @@ namespace Nuake
|
||||
RenderCommand::Disable(RendererEnum::DEPTH_TEST);
|
||||
}
|
||||
|
||||
shader->SetUniformVec4("u_Color", shape.LineColor);
|
||||
shader->SetUniform("u_Color", shape.LineColor);
|
||||
|
||||
glLineWidth(shape.Width);
|
||||
Matrix4 view = mView;
|
||||
@@ -1125,7 +1132,7 @@ namespace Nuake
|
||||
view = glm::translate(view, shape.Position) * rotationMatrix;
|
||||
view = glm::scale(view, reinterpret_cast<Physics::Box*>(shape.Shape.get())->GetSize());
|
||||
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniform("u_View", view);
|
||||
|
||||
mBoxGizmo->Bind();
|
||||
RenderCommand::DrawLines(0, 26);
|
||||
@@ -1138,7 +1145,7 @@ namespace Nuake
|
||||
|
||||
view = glm::translate(view, shape.Position) * rotationMatrix;
|
||||
view = glm::scale(view, Vector3(reinterpret_cast<Physics::Sphere*>(shape.Shape.get())->GetRadius()));
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniform("u_View", view);
|
||||
|
||||
mSphereGizmo->Bind();
|
||||
RenderCommand::DrawLines(0, 128);
|
||||
@@ -1151,7 +1158,7 @@ namespace Nuake
|
||||
|
||||
view = glm::translate(view, shape.Position) * rotationMatrix;
|
||||
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniform("u_View", view);
|
||||
|
||||
const Physics::Capsule* capsule = reinterpret_cast<Physics::Capsule*>(shape.Shape.get());
|
||||
mCapsuleGizmo->UpdateShape(capsule->GetRadius(), capsule->GetHeight());
|
||||
@@ -1168,7 +1175,7 @@ namespace Nuake
|
||||
|
||||
const Physics::Cylinder* cylinder = reinterpret_cast<Physics::Cylinder*>(shape.Shape.get());
|
||||
|
||||
shader->SetUniformMat4f("u_View", view);
|
||||
shader->SetUniform("u_View", view);
|
||||
|
||||
mCylinderGizmo->Bind();
|
||||
mCylinderGizmo->UpdateShape(cylinder->GetRadius(), cylinder->GetHeight());
|
||||
@@ -1190,7 +1197,7 @@ namespace Nuake
|
||||
if (auto entity = scene.GetEntity(child.Name); entity.GetHandle() != -1)
|
||||
{
|
||||
const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(child.Id) + "]";
|
||||
shader->SetUniformMat4f(boneMatrixUniformName, child.FinalTransform);
|
||||
shader->SetUniform(boneMatrixUniformName, child.FinalTransform);
|
||||
}
|
||||
|
||||
SetSkeletonBoneTransformRecursive(scene, child, shader);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nuake
|
||||
!fileContent.empty())
|
||||
{
|
||||
Source = ParseShader(fileContent);
|
||||
ProgramId = CreateProgram(Source);
|
||||
programId = CreateProgram(Source);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ namespace Nuake
|
||||
Path = filePath;
|
||||
|
||||
Source = ParseShader(content);
|
||||
ProgramId = CreateProgram(Source);
|
||||
programId = CreateProgram(Source);
|
||||
}
|
||||
|
||||
bool Shader::Rebuild()
|
||||
@@ -51,7 +51,7 @@ namespace Nuake
|
||||
return false;
|
||||
|
||||
Source = newSource;
|
||||
ProgramId = newProgramId;
|
||||
programId = newProgramId;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace Nuake
|
||||
// Bind the shader
|
||||
void Shader::Bind() const
|
||||
{
|
||||
glUseProgram(ProgramId);
|
||||
glUseProgram(programId);
|
||||
}
|
||||
|
||||
// unbind the shader
|
||||
@@ -220,7 +220,7 @@ namespace Nuake
|
||||
{
|
||||
if (UniformCache.find(uniform) == UniformCache.end())
|
||||
{
|
||||
int addr = glGetUniformLocation(ProgramId, uniform.c_str());
|
||||
int addr = glGetUniformLocation(programId, uniform.c_str());
|
||||
|
||||
if (addr == -1)
|
||||
return addr;
|
||||
@@ -234,125 +234,166 @@ namespace Nuake
|
||||
}
|
||||
|
||||
// Uniforms
|
||||
|
||||
void Shader::SetUniformVec4(const std::string& name, Vector4 vec)
|
||||
void Shader::SetUniforms(const std::vector<UniformVariable>& uniforms)
|
||||
{
|
||||
SetUniform4f(name, vec.x, vec.y, vec.z, vec.w);
|
||||
for (auto& u : uniforms)
|
||||
{
|
||||
std::string name = u.name;
|
||||
auto type = u.type;
|
||||
switch (type)
|
||||
{
|
||||
case UniformTypes::Float:
|
||||
SetUniform(name, u.value.valueFloat);
|
||||
break;
|
||||
case UniformTypes::Int:
|
||||
SetUniform(name, u.value.valueInt);
|
||||
break;
|
||||
case UniformTypes::Uint:
|
||||
SetUniform(name, u.value.valueUInt);
|
||||
break;
|
||||
case UniformTypes::Vec2:
|
||||
SetUniform(name, u.value.valueVec2);
|
||||
break;
|
||||
case UniformTypes::Vec3:
|
||||
SetUniform(name, u.value.valueVec3);
|
||||
break;
|
||||
case UniformTypes::Vec4:
|
||||
SetUniform(name, u.value.valueVec4);
|
||||
break;
|
||||
case UniformTypes::Mat3:
|
||||
SetUniform(name, u.value.valueMat3);
|
||||
break;
|
||||
case UniformTypes::Mat4:
|
||||
SetUniform(name, u.value.valueMat4);
|
||||
break;
|
||||
case UniformTypes::Sampler2D:
|
||||
SetUniform(name, u.value.valueInt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniformVec3(const std::string& name, Vector3 vec)
|
||||
{
|
||||
SetUniform3f(name, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
void Shader::SetUniformVec2(const std::string& name, Vector2 vec)
|
||||
{
|
||||
SetUniform2f(name, vec.x, vec.y);
|
||||
}
|
||||
|
||||
void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3)
|
||||
void Shader::SetUniform(const std::string& name, float v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
|
||||
if (addr != -1)
|
||||
glUniform4f(addr, v0, v1, v2, v3);
|
||||
{
|
||||
glUniform1f(addr, v0);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform3f(const std::string& name, float v0, float v1, float v2)
|
||||
void Shader::SetUniform(const std::string& name, int v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
|
||||
if (addr != -1)
|
||||
glUniform3f(addr, v0, v1, v2);
|
||||
glUniform1i(addr, v0);
|
||||
}
|
||||
|
||||
void Shader::SetUniform2f(const std::string& name, float v0, float v1)
|
||||
void Shader::SetUniform(const std::string& name, unsigned int v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
|
||||
if (addr != -1)
|
||||
glUniform2f(addr, v0, v1);
|
||||
glUniform1ui(addr, v0);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1i(const std::string& name, int v0)
|
||||
void Shader::SetUniform(const std::string& name, Vector2 v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
|
||||
if (addr != -1)
|
||||
SetUniform1i(addr, v0);
|
||||
SetUniform(name, v0.x, v0.y);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1i(uint32_t location, int v0)
|
||||
{
|
||||
glUniform1i(location, v0);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1iv(const std::string& name, int size, int* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
if (addr != -1)
|
||||
glUniform1iv(addr, size, value);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1fv(const std::string& name, int size, float* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
if (addr != -1)
|
||||
glUniform1fv(addr, size, value);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat3f(const std::string& name, Matrix3 mat)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
if(addr != -1)
|
||||
glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat4f(uint32_t location, const Matrix4& mat)
|
||||
{
|
||||
glUniformMatrix4fv(location, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat4f(const std::string& name, const Matrix4& mat)
|
||||
void Shader::SetUniform(const std::string& name, float v0, float v1)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
|
||||
if (addr != -1)
|
||||
{
|
||||
SetUniformMat4f(addr, mat);
|
||||
glUniform2f(addr, v0, v1);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform1f(const std::string& name, float v0)
|
||||
void Shader::SetUniform(const std::string& name, float v0, float v1, float v2)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
//ASSERT(addr != -1);
|
||||
|
||||
if (addr != -1)
|
||||
glUniform1f(addr, v0);
|
||||
{
|
||||
glUniform3f(addr, v0, v1, v2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Shader::SetUniformTex(const std::string& name, Texture* texture, unsigned int slot)
|
||||
void Shader::SetUniform(const std::string& name, Vector3 v0)
|
||||
{
|
||||
//ASSERT(texture != nullptr);
|
||||
|
||||
SetUniform1i(name, slot);
|
||||
texture->Bind(slot);
|
||||
SetUniform(name, v0.x, v0.y, v0.z);
|
||||
}
|
||||
|
||||
void Shader::SetUniformTex(const std::string& name, Ref<Texture> texture, unsigned int slot)
|
||||
void Shader::SetUniform(const std::string& name, float v0, float v1, float v2, float v3)
|
||||
{
|
||||
//ASSERT(texture != nullptr);
|
||||
int addr = FindUniformLocation(name);
|
||||
|
||||
SetUniform1i(name, slot);
|
||||
if (addr != -1)
|
||||
{
|
||||
glUniform4f(addr, v0, v1, v2, v3);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, Vector4 v0)
|
||||
{
|
||||
SetUniform(name, v0.x, v0.y, v0.z, v0.w);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, Matrix3 v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
|
||||
if (addr != -1)
|
||||
{
|
||||
glUniformMatrix3fv(addr, 1, GL_FALSE, &v0[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, Matrix4 v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
if (addr != -1)
|
||||
{
|
||||
glUniformMatrix4fv(addr, 1, GL_FALSE, &v0[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniformv(const std::string & name, int size, int* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
if (addr != -1)
|
||||
{
|
||||
glUniform1iv(addr, size, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string & name, int size, float* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
if (addr != -1)
|
||||
{
|
||||
glUniform1fv(addr, size, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, bool value)
|
||||
{
|
||||
SetUniform(name, value);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(uint32_t uniformSlot, int value)
|
||||
{
|
||||
glUniform1i(uniformSlot, value);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(uint32_t uniformSlot, Matrix4 value)
|
||||
{
|
||||
glUniformMatrix4fv(uniformSlot, 1, GL_FALSE, &value[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& uniformName, Texture* texture, uint32_t slot)
|
||||
{
|
||||
SetUniform(uniformName, slot);
|
||||
texture->Bind(slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,41 +18,134 @@ namespace Nuake
|
||||
std::string ComputeShader;
|
||||
};
|
||||
|
||||
enum class UniformTypes
|
||||
{
|
||||
Int, Uint, Float, Bool, Vec2, Vec3, Vec4, Mat3, Mat4, Sampler2D
|
||||
};
|
||||
|
||||
union UniformValue
|
||||
{
|
||||
float valueFloat;
|
||||
int valueInt;
|
||||
unsigned int valueUInt;
|
||||
Vector2 valueVec2;
|
||||
Vector3 valueVec3;
|
||||
Vector4 valueVec4;
|
||||
Matrix3 valueMat3;
|
||||
Matrix4 valueMat4;
|
||||
};
|
||||
|
||||
struct UniformVariable
|
||||
{
|
||||
std::string name;
|
||||
UniformValue value;
|
||||
UniformTypes type;
|
||||
|
||||
UniformVariable(const std::string& uniformName, float uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueFloat = uniformValue;
|
||||
type = UniformTypes::Float;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, int uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueInt = uniformValue;
|
||||
type = UniformTypes::Int;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, bool uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueInt = static_cast<int>(uniformValue);
|
||||
type = UniformTypes::Int;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, Vector2 uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueVec2 = uniformValue;
|
||||
type = UniformTypes::Vec2;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, Vector3 uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueVec3 = uniformValue;
|
||||
type = UniformTypes::Vec3;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, Vector4 uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueVec4 = uniformValue;
|
||||
type = UniformTypes::Vec4;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, Matrix3 uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueMat3 = uniformValue;
|
||||
type = UniformTypes::Mat3;
|
||||
}
|
||||
|
||||
UniformVariable(const std::string& uniformName, Matrix4 uniformValue)
|
||||
{
|
||||
name = uniformName;
|
||||
value.valueMat4 = uniformValue;
|
||||
type = UniformTypes::Mat4;
|
||||
}
|
||||
};
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
private:
|
||||
uint32_t programId;
|
||||
std::string Path;
|
||||
ShaderSource Source;
|
||||
unsigned int ProgramId;
|
||||
|
||||
std::unordered_map<std::string, int> UniformCache;
|
||||
|
||||
Shader(const std::string& filePath);
|
||||
std::map<std::string, unsigned int> mUniforms;
|
||||
std::map<std::string, UniformTypes> mUniformsType;
|
||||
std::string mError = "";
|
||||
|
||||
public:
|
||||
Shader(const std::string& filePath);
|
||||
Shader(const std::string& path, const std::string& content);
|
||||
|
||||
bool Rebuild();
|
||||
|
||||
void Bind() const;
|
||||
void Unbind() const;
|
||||
|
||||
void SetUniformVec4(const std::string& name, Vector4 vec);
|
||||
void SetUniformVec3(const std::string& name, Vector3 vec);
|
||||
void SetUniformVec2(const std::string& name, Vector2 vec);
|
||||
void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
|
||||
void SetUniform3f(const std::string& name, float v0, float v1, float v2);
|
||||
void SetUniform2f(const std::string& name, float v0, float v1);
|
||||
void SetUniform1f(const std::string& name, float v0);
|
||||
void SetUniform1b(const std::string& name, bool v0);
|
||||
void SetUniformTex(const std::string& name, Texture* texture, unsigned int slot = 0);
|
||||
void SetUniformTex(const std::string& name, Ref<Texture> texture, unsigned int slot = 0);
|
||||
void SetUniform1i(const std::string& name, int v0);
|
||||
void SetUniform1i(uint32_t location, int v0);
|
||||
std::map<std::string, UniformTypes> GetUniforms()
|
||||
{
|
||||
return mUniformsType;
|
||||
}
|
||||
|
||||
void SetUniform1iv(const std::string& name, int size, int* value);
|
||||
void SetUniform1fv(const std::string& name, int size, float* value);
|
||||
void SetUniformMat3f(const std::string& name, Matrix3 mat);
|
||||
std::string GetError() const { return mError; }
|
||||
|
||||
void SetUniformMat4f(uint32_t name, const Matrix4& mat);
|
||||
void SetUniformMat4f(const std::string& name, const Matrix4& mat);
|
||||
void SetUniforms(const std::vector<UniformVariable>& uniforms);
|
||||
|
||||
void SetUniform(const std::string& name, float v0);
|
||||
void SetUniform(const std::string& name, int v0);
|
||||
void SetUniform(const std::string& name, unsigned int v0);
|
||||
void SetUniform(const std::string& name, float v0, float v1);
|
||||
void SetUniform(const std::string& name, Vector2 v0);
|
||||
void SetUniform(const std::string& name, float v0, float v1, float v3);
|
||||
void SetUniform(const std::string& name, Vector3 v0);
|
||||
void SetUniform(const std::string& name, float v0, float v1, float v3, float v4);
|
||||
void SetUniform(const std::string& name, Vector4 v0);
|
||||
void SetUniform(const std::string& name, Matrix3 v0);
|
||||
void SetUniform(const std::string& name, Matrix4 v0);
|
||||
void SetUniformv(const std::string& name, int size, int* value);
|
||||
void SetUniform(const std::string& name, int size, float* value);
|
||||
void SetUniform(const std::string& name, bool value);
|
||||
void SetUniform(uint32_t uniformSlot, int value);
|
||||
void SetUniform(uint32_t uniformSlot, Matrix4 value);
|
||||
void SetUniform(const std::string& name, Texture* texture, uint32_t slot);
|
||||
|
||||
int FindUniformLocation(std::string uniform);
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
m_DefaultAlbedo->Bind(4);
|
||||
shader->SetUniform1i("m_Albedo", 4);
|
||||
shader->SetUniform("m_Albedo", 4);
|
||||
|
||||
// AO
|
||||
if (m_AO != nullptr)
|
||||
@@ -117,7 +117,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
m_DefaultAO->Bind(5);
|
||||
shader->SetUniform1i("m_AO", 5);
|
||||
shader->SetUniform("m_AO", 5);
|
||||
|
||||
// Metallic
|
||||
if (m_Metalness != nullptr) {
|
||||
@@ -126,7 +126,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
m_DefaultMetalness->Bind(6);
|
||||
shader->SetUniform1i("m_Metalness", 6);
|
||||
shader->SetUniform("m_Metalness", 6);
|
||||
|
||||
// Roughness
|
||||
if (m_Roughness != nullptr) {
|
||||
@@ -135,7 +135,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
m_DefaultRoughness->Bind(7);
|
||||
shader->SetUniform1i("m_Roughness", 7);
|
||||
shader->SetUniform("m_Roughness", 7);
|
||||
|
||||
// Normal
|
||||
if (m_Normal != nullptr) {
|
||||
@@ -145,7 +145,7 @@ namespace Nuake
|
||||
else
|
||||
m_DefaultNormal->Bind(8);
|
||||
|
||||
shader->SetUniform1i("m_Normal", 8);
|
||||
shader->SetUniform("m_Normal", 8);
|
||||
|
||||
// Displacement
|
||||
if (m_Displacement != nullptr)
|
||||
@@ -158,8 +158,8 @@ namespace Nuake
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UBOStructure), &data);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 32, UBO);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
//Renderer::m_Shader->SetUniform("m_Displacement", 9);
|
||||
//Renderer::m_Shader->SetUniform("m_Displacement", 9);
|
||||
}
|
||||
|
||||
void Material::SetupUniformBuffer()
|
||||
|
||||
@@ -41,6 +41,24 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(Vector2 size, void* data)
|
||||
{
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)GL_RGBA, size.x, size.y, 0, (GLenum)GL_RGBA, (GLenum)GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Texture::Texture(Vector2 size, GLenum format, GLenum format2, GLenum format3, void* data)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Nuake
|
||||
public:
|
||||
Texture(const std::string& path); // Load texture from file
|
||||
Texture(unsigned char* data, int len); // Used to load texture from a memory buffer
|
||||
|
||||
Texture(Vector2 size, void* data);
|
||||
Texture(Vector2 size, GLenum format, GLenum format2 = 0, GLenum format3 = 0, void* data = 0); // Used to load texture from memeory with known size
|
||||
~Texture();
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Nuake
|
||||
template<typename T>
|
||||
T& AddComponent()
|
||||
{
|
||||
T& component = m_Scene->m_Registry.emplace_or_replace <T>(m_EntityHandle);
|
||||
T& component = m_Scene->m_Registry.emplace_or_replace<T>(m_EntityHandle);
|
||||
return component;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,41 +37,41 @@ namespace Nuake
|
||||
void ProceduralSky::Draw(Matrix4 projection, Matrix4 view) {
|
||||
Shader* skyShader = ShaderManager::GetShader("Resources/Shaders/atmospheric_sky.shader");
|
||||
skyShader->Bind();
|
||||
skyShader->SetUniform1f("SurfaceRadius", SurfaceRadius);
|
||||
skyShader->SetUniform1f("AtmosphereRadius", AtmosphereRadius);
|
||||
skyShader->SetUniform1f("SunIntensity", SunIntensity);
|
||||
skyShader->SetUniform("SurfaceRadius", SurfaceRadius);
|
||||
skyShader->SetUniform("AtmosphereRadius", AtmosphereRadius);
|
||||
skyShader->SetUniform("SunIntensity", SunIntensity);
|
||||
|
||||
skyShader->SetUniform3f("RayleighScattering",
|
||||
skyShader->SetUniform("RayleighScattering",
|
||||
RayleighScattering.r,
|
||||
RayleighScattering.g,
|
||||
RayleighScattering.b);
|
||||
|
||||
skyShader->SetUniform3f("MieScattering",
|
||||
skyShader->SetUniform("MieScattering",
|
||||
MieScattering.r,
|
||||
MieScattering.g,
|
||||
MieScattering.b);
|
||||
|
||||
skyShader->SetUniform3f("CenterPoint",
|
||||
skyShader->SetUniform("CenterPoint",
|
||||
CenterPoint.x,
|
||||
CenterPoint.y,
|
||||
CenterPoint.z);
|
||||
|
||||
skyShader->SetUniform3f("SunDirection",
|
||||
skyShader->SetUniform("SunDirection",
|
||||
SunDirection.x,
|
||||
SunDirection.y,
|
||||
SunDirection.z);
|
||||
|
||||
skyShader->SetUniformMat4f("Projection", projection);
|
||||
skyShader->SetUniformMat4f("View", view);
|
||||
skyShader->SetUniform("Projection", projection);
|
||||
skyShader->SetUniform("View", view);
|
||||
//glm::vec3 CamRight = cam->cameraRight;
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform3f("CamRight",
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform("CamRight",
|
||||
// CamRight.x,
|
||||
// CamRight.y,
|
||||
// CamRight.z);
|
||||
//
|
||||
//glm::vec3 CamUp = cam->cameraUp;//glm::normalize(glm::cross(CameraDirection, CamRight));
|
||||
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform3f("CamUp",
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform("CamUp",
|
||||
// CamUp.x,
|
||||
// CamUp.y,
|
||||
// CamUp.z);
|
||||
|
||||
@@ -75,26 +75,26 @@ namespace Nuake
|
||||
m_Hdr->Bind(4);
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
m_Hdr->BindCubemap(5);
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection);
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", view);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", projection);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", view);
|
||||
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 4);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 4);
|
||||
Renderer::m_SkyboxShader->SetUniform("skybox", 5);
|
||||
|
||||
// ... set view and projection matrix
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glDepthMask(GL_TRUE);
|
||||
//Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
//Renderer::m_Shader->SetUniform("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
void Skybox::Push()
|
||||
{
|
||||
m_Hdr->BindCubemap(5);
|
||||
Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 5);
|
||||
Renderer::m_Shader->SetUniform("u_IrradianceMap", 5);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,17 +139,17 @@ namespace Nuake
|
||||
|
||||
// convert HDR equirectangular environment map to cubemap equivalent
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 5);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", captureViews[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
@@ -85,20 +85,20 @@ namespace Nuake {
|
||||
m_HDRTexture->Bind(6);
|
||||
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection);
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", view);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", projection);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", view);
|
||||
Renderer::m_SkyboxShader->SetUniform("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform("skybox", 5);
|
||||
|
||||
// ... set view and projection matrix
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glDepthMask(GL_TRUE);
|
||||
//Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
//Renderer::m_Shader->SetUniform("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void SkyboxHDR::Push() {
|
||||
@@ -112,13 +112,13 @@ namespace Nuake {
|
||||
glActiveTexture(GL_TEXTURE0 + 3);
|
||||
glBindTexture(GL_TEXTURE_2D, m_brdLut);
|
||||
|
||||
Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 1);
|
||||
Renderer::m_Shader->SetUniform1i("prefilterMap", 2);
|
||||
Renderer::m_Shader->SetUniform1i("brdfLUT", 3);
|
||||
Renderer::m_Shader->SetUniform("u_IrradianceMap", 1);
|
||||
Renderer::m_Shader->SetUniform("prefilterMap", 2);
|
||||
Renderer::m_Shader->SetUniform("brdfLUT", 3);
|
||||
|
||||
Renderer::m_DeferredShader->SetUniform1i("u_IrradianceMap", 1);
|
||||
Renderer::m_DeferredShader->SetUniform1i("u_PrefilterMap", 2);
|
||||
Renderer::m_DeferredShader->SetUniform1i("u_BrdfLUT", 3);
|
||||
Renderer::m_DeferredShader->SetUniform("u_IrradianceMap", 1);
|
||||
Renderer::m_DeferredShader->SetUniform("u_PrefilterMap", 2);
|
||||
Renderer::m_DeferredShader->SetUniform("u_BrdfLUT", 3);
|
||||
}
|
||||
|
||||
void SkyboxHDR::CreateHDRCubemap() {
|
||||
@@ -160,11 +160,11 @@ namespace Nuake {
|
||||
m_HDRTexture->Bind(5);
|
||||
// convert HDR equirectangular environment map to cubemap equivalent
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 5);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace Nuake {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", captureViews[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_Cubemap, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -224,18 +224,18 @@ namespace Nuake {
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
|
||||
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform("convulate", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform("prefilter", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform("skybox", 5);
|
||||
|
||||
glViewport(0, 0, 32, 32); // don't forget to configure the viewport to the capture dimensions.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", captureViews[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_ConvulatedCubemap, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -281,12 +281,12 @@ namespace Nuake {
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
|
||||
Renderer::m_SkyboxShader->SetUniform("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("prefilter", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform("equirectangularMap", 6);
|
||||
Renderer::m_SkyboxShader->SetUniform("skybox", 5);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
unsigned int maxMipLevels = 5;
|
||||
@@ -300,10 +300,10 @@ namespace Nuake {
|
||||
glViewport(0, 0, mipWidth, mipHeight);
|
||||
|
||||
float roughness = (float)mip / (float)(maxMipLevels - 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1f("roughness", roughness);
|
||||
Renderer::m_SkyboxShader->SetUniform("roughness", roughness);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
|
||||
Renderer::m_SkyboxShader->SetUniform("view", captureViews[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_SpecularCubemap, mip);
|
||||
|
||||
|
||||
82
Nuake/src/UI/DataBinding/DataBindObject.cpp
Normal file
82
Nuake/src/UI/DataBinding/DataBindObject.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "DataBindObject.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
DataBindObject::DataBindObject(const std::string& name, int* value)
|
||||
: Name(name), Data(value)
|
||||
{
|
||||
Type = DataBindType::Int;
|
||||
}
|
||||
|
||||
DataBindObject::DataBindObject(const std::string& name, float* value)
|
||||
: Name(name), Data(value)
|
||||
{
|
||||
Type = DataBindType::Float;
|
||||
}
|
||||
|
||||
DataBindObject::DataBindObject(const std::string& name, bool* value)
|
||||
: Name(name), Data(value)
|
||||
{
|
||||
Type = DataBindType::Bool;
|
||||
}
|
||||
|
||||
DataBindObject::DataBindObject(const std::string& name, std::string* value)
|
||||
: Name(name), Data(value)
|
||||
{
|
||||
Type = DataBindType::String;
|
||||
}
|
||||
|
||||
DataBindObject::DataBindObject(const std::string& name, char* value)
|
||||
: Name(name), Data(value)
|
||||
{
|
||||
Type = DataBindType::Char;
|
||||
}
|
||||
|
||||
void DataBindObject::SetData(int* value)
|
||||
{
|
||||
Data = value;
|
||||
}
|
||||
|
||||
void DataBindObject::SetData(bool* value)
|
||||
{
|
||||
Data = value;
|
||||
}
|
||||
|
||||
void DataBindObject::SetData(std::string* value)
|
||||
{
|
||||
Data = value;
|
||||
}
|
||||
|
||||
void DataBindObject::SetData(float* value)
|
||||
{
|
||||
Data = value;
|
||||
}
|
||||
|
||||
void DataBindObject::SetData(char* value)
|
||||
{
|
||||
Data = value;
|
||||
}
|
||||
|
||||
std::variant<int*, float*, bool*, std::string*, char*> DataBindObject::GetData()
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
|
||||
DataModel::DataModel(const std::string& name)
|
||||
: Name(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool DataModel::HasData(const std::string& dataName)
|
||||
{
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
191
Nuake/src/UI/DataBinding/DataBindObject.h
Normal file
191
Nuake/src/UI/DataBinding/DataBindObject.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
#include <cassert>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
enum class DataBindType
|
||||
{
|
||||
Int, Float, Bool, String, Char
|
||||
};
|
||||
|
||||
class DataBindObject
|
||||
{
|
||||
private:
|
||||
DataBindType Type;
|
||||
|
||||
public:
|
||||
std::string Name;
|
||||
|
||||
std::variant<int*, float*, bool*, std::string*, char*> Data;
|
||||
|
||||
DataBindObject(const std::string& name, int* data);
|
||||
DataBindObject(const std::string& name, float* data);
|
||||
DataBindObject(const std::string& name, bool* data);
|
||||
DataBindObject(const std::string& name, std::string* data);
|
||||
DataBindObject(const std::string& name, char* data);
|
||||
|
||||
void SetData(int* value);
|
||||
void SetData(float* value);
|
||||
void SetData(bool* value);
|
||||
void SetData(std::string* value);
|
||||
void SetData(char* value);
|
||||
|
||||
DataBindType GetType() const { return Type; }
|
||||
|
||||
std::variant<int*, float*, bool*, std::string*, char*> GetData();
|
||||
};
|
||||
|
||||
class DataModel;
|
||||
typedef std::shared_ptr<DataModel> DataModelPtr;
|
||||
|
||||
class DataModel
|
||||
{
|
||||
public:
|
||||
std::vector<DataBindObject> DataObjects;
|
||||
std::string Name;
|
||||
|
||||
static DataModelPtr New(const std::string& name)
|
||||
{
|
||||
return std::make_shared<DataModel>(name);
|
||||
}
|
||||
|
||||
DataModel(const std::string& modelName);
|
||||
~DataModel() = default;
|
||||
|
||||
void Bind(const std::string& dataName, int* data)
|
||||
{
|
||||
DataBindObject dataBindObject = DataBindObject(dataName, data);
|
||||
DataObjects.push_back(dataBindObject);
|
||||
}
|
||||
|
||||
void Bind(const std::string& dataName, float* data)
|
||||
{
|
||||
DataBindObject dataBindObject = DataBindObject(dataName, data);
|
||||
DataObjects.push_back(dataBindObject);
|
||||
}
|
||||
|
||||
void Bind(const std::string& dataName, bool* data)
|
||||
{
|
||||
DataBindObject dataBindObject = DataBindObject(dataName, data);
|
||||
DataObjects.push_back(dataBindObject);
|
||||
}
|
||||
|
||||
void Bind(const std::string& dataName, std::string* data)
|
||||
{
|
||||
DataBindObject dataBindObject = DataBindObject(dataName, data);
|
||||
DataObjects.push_back(dataBindObject);
|
||||
}
|
||||
|
||||
void Bind(const std::string& dataName, char* data)
|
||||
{
|
||||
DataBindObject dataBindObject = DataBindObject(dataName, data);
|
||||
DataObjects.push_back(dataBindObject);
|
||||
}
|
||||
|
||||
bool HasData(const std::string& dataName);
|
||||
|
||||
DataBindType GetDataType(const std::string dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name");
|
||||
|
||||
for (auto& dataObject : DataObjects)
|
||||
{
|
||||
if (dataObject.Name == dataName)
|
||||
{
|
||||
return dataObject.GetType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(false && "Unsupported data type");
|
||||
}
|
||||
|
||||
template<>
|
||||
bool& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name.");
|
||||
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
return *std::get<bool*>(dataBindObject.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
int& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name.");
|
||||
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
auto variant = dataBindObject.GetData();
|
||||
int* data = std::get<int*>(variant);
|
||||
return *data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
float& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name.");
|
||||
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
auto variant = dataBindObject.GetData();
|
||||
float* data = std::get<float*>(variant);
|
||||
return *data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name.");
|
||||
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
auto variant = dataBindObject.GetData();
|
||||
std::string* data = std::get<std::string*>(variant);
|
||||
return *data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
char& GetData(const std::string& dataName)
|
||||
{
|
||||
assert(HasData(dataName) && "Model has no data with that name.");
|
||||
|
||||
for (auto& dataBindObject : DataObjects)
|
||||
{
|
||||
if (dataBindObject.Name == dataName)
|
||||
{
|
||||
auto variant = dataBindObject.GetData();
|
||||
char* data = std::get<char*>(variant);
|
||||
return *data;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
10
Nuake/src/UI/DataBinding/DataBindOperation.h
Normal file
10
Nuake/src/UI/DataBinding/DataBindOperation.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
enum class DataBindOperationType
|
||||
{
|
||||
If,
|
||||
|
||||
};
|
||||
}
|
||||
50
Nuake/src/UI/DataBinding/DataModelOperations.cpp
Normal file
50
Nuake/src/UI/DataBinding/DataModelOperations.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "DataModelOperations.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
DataModelOperation::DataModelOperation(const std::string& name, OperationType type, ComparaisonType compType)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
CompType = compType;
|
||||
}
|
||||
|
||||
DataModelOperationPtr DataModelOperation::New(const std::string& name, OperationType type, ComparaisonType compType)
|
||||
{
|
||||
return std::make_shared<DataModelOperation>(name, type, compType);
|
||||
}
|
||||
|
||||
bool DataModelOperation::Compare(DataModelPtr object)
|
||||
{
|
||||
if (!object || !object->HasData(Name))
|
||||
{
|
||||
std::cout << "DataModel has no data named " << Name << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
DataBindType dataType = object->GetDataType(Name);
|
||||
auto dataRight = Right;
|
||||
|
||||
switch (dataType)
|
||||
{
|
||||
case DataBindType::Bool:
|
||||
return CompareLeftAndRight<bool>(object->GetData<bool>(Name), std::get<bool>(Right), CompType);
|
||||
break;
|
||||
case DataBindType::Int:
|
||||
return CompareLeftAndRight<int>(object->GetData<int>(Name), std::get<int>(Right), CompType);
|
||||
break;
|
||||
case DataBindType::Float:
|
||||
return CompareLeftAndRight<float>(object->GetData<float>(Name), std::get<float>(Right), CompType);
|
||||
break;
|
||||
case DataBindType::String:
|
||||
return CompareLeftAndRight<std::string>(object->GetData<std::string>(Name), std::get<std::string>(Right), CompType);
|
||||
break;
|
||||
case DataBindType::Char:
|
||||
return CompareLeftAndRight<char>(object->GetData<char>(Name), std::get<char>(Right), CompType);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
75
Nuake/src/UI/DataBinding/DataModelOperations.h
Normal file
75
Nuake/src/UI/DataBinding/DataModelOperations.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include "DataBindObject.h"
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
enum class OperationType
|
||||
{
|
||||
If, IfClass
|
||||
};
|
||||
|
||||
enum class ComparaisonType
|
||||
{
|
||||
Equal,
|
||||
NotEqual,
|
||||
GreaterOrEqual,
|
||||
LessOrEqual,
|
||||
Greater,
|
||||
Less,
|
||||
None
|
||||
};
|
||||
|
||||
class DataModelOperation;
|
||||
typedef std::shared_ptr<DataModelOperation> DataModelOperationPtr;
|
||||
typedef std::vector<DataModelOperationPtr> DataModelOperationCollection;
|
||||
class DataModelOperation
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string ClassName;
|
||||
|
||||
OperationType Type;
|
||||
ComparaisonType CompType;
|
||||
|
||||
std::variant<int, float, bool, std::string, char> Right;
|
||||
|
||||
static DataModelOperationPtr New(const std::string& name, OperationType type, ComparaisonType compType);
|
||||
DataModelOperation(const std::string& name, OperationType type, ComparaisonType compType);
|
||||
~DataModelOperation() = default;
|
||||
|
||||
template<typename T>
|
||||
bool CompareLeftAndRight(const T& left, const T& right, const ComparaisonType& compType)
|
||||
{
|
||||
if (CompType == ComparaisonType::Equal)
|
||||
{
|
||||
return left == right;
|
||||
}
|
||||
else if (CompType == ComparaisonType::NotEqual)
|
||||
{
|
||||
return left != right;
|
||||
}
|
||||
else if (CompType == ComparaisonType::GreaterOrEqual)
|
||||
{
|
||||
return left >= right;
|
||||
}
|
||||
else if (CompType == ComparaisonType::LessOrEqual)
|
||||
{
|
||||
return left <= right;
|
||||
}
|
||||
else if (CompType == ComparaisonType::Greater)
|
||||
{
|
||||
return left > right;
|
||||
}
|
||||
else if (CompType == ComparaisonType::Less)
|
||||
{
|
||||
return left < right;
|
||||
}
|
||||
}
|
||||
|
||||
bool Compare(DataModelPtr object);
|
||||
};
|
||||
}
|
||||
34
Nuake/src/UI/FileSystem.cpp
Normal file
34
Nuake/src/UI/FileSystem.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "FileSystem.h"
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
namespace FileSystem
|
||||
{
|
||||
bool FileExists(const std::string& path)
|
||||
{
|
||||
return std::filesystem::exists(path);
|
||||
}
|
||||
|
||||
std::string ReadFile(const std::string& path)
|
||||
{
|
||||
if (!FileExists(path))
|
||||
return "";
|
||||
|
||||
std::string fileContent;
|
||||
std::string currentLine;
|
||||
|
||||
std::ifstream file(path);
|
||||
|
||||
while (getline(file, currentLine))
|
||||
{
|
||||
fileContent += currentLine + "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
return fileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Nuake/src/UI/FileSystem.h
Normal file
11
Nuake/src/UI/FileSystem.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
namespace FileSystem
|
||||
{
|
||||
bool FileExists(const std::string& path);
|
||||
std::string ReadFile(const std::string& path);
|
||||
};
|
||||
}
|
||||
35
Nuake/src/UI/Font/Font.cpp
Normal file
35
Nuake/src/UI/Font/Font.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "Font.h"
|
||||
#include "../FileSystem.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<Font> Font::New(const std::string& path)
|
||||
{
|
||||
return std::make_shared<Font>(path);
|
||||
}
|
||||
|
||||
Font::Font(const std::string& path)
|
||||
{
|
||||
mFreeTypeHandle = msdfgen::initializeFreetype();
|
||||
Load(path);
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
{
|
||||
msdfgen::destroyFont(mFontHandle);
|
||||
}
|
||||
|
||||
bool Font::Load(const std::string& path)
|
||||
{
|
||||
bool exists = FileSystem::FileExists(path);
|
||||
mFontHandle = msdfgen::loadFont(mFreeTypeHandle, path.c_str());
|
||||
if (!mFontHandle)
|
||||
return false;
|
||||
|
||||
msdfgen::FontMetrics metrics;
|
||||
msdfgen::getFontMetrics(metrics, mFontHandle);
|
||||
|
||||
LineHeight = (float)metrics.lineHeight;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
93
Nuake/src/UI/Font/Font.h
Normal file
93
Nuake/src/UI/Font/Font.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include <src/Core/Maths.h>
|
||||
#include <msdf-atlas-gen/msdf-atlas-gen.h>
|
||||
#include <msdfgen/ext/import-font.h>
|
||||
|
||||
#include <src/Rendering/Textures/Texture.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
struct CharPos
|
||||
{
|
||||
double left;
|
||||
double right;
|
||||
double top;
|
||||
double bottom;
|
||||
};
|
||||
|
||||
struct CharUV
|
||||
{
|
||||
Vector2 Pos;
|
||||
Vector2 Size;
|
||||
};
|
||||
|
||||
class Char
|
||||
{
|
||||
private:
|
||||
unsigned int m_VBO;
|
||||
unsigned int m_VAO;
|
||||
|
||||
public:
|
||||
unsigned int Unicode;
|
||||
float Advance;
|
||||
CharPos PlaneBounds;
|
||||
CharUV AtlasBounds;
|
||||
|
||||
Char() {};
|
||||
Char(const unsigned int unicode, float advance, CharPos plane, CharUV atlas)
|
||||
{
|
||||
Unicode = unicode;
|
||||
Advance = advance;
|
||||
PlaneBounds = plane;
|
||||
AtlasBounds = atlas;
|
||||
}
|
||||
|
||||
CharUV GetAtlasUV(const Vector2& atlasSize)
|
||||
{
|
||||
return AtlasBounds;
|
||||
}
|
||||
};
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
Font(const std::string& path);
|
||||
Font() = default;
|
||||
~Font();
|
||||
|
||||
float LineHeight = 0.f;
|
||||
|
||||
static std::shared_ptr<Font> New(const std::string& path);
|
||||
|
||||
msdfgen::FontHandle* GetFontHandle() const { return mFontHandle; }
|
||||
|
||||
void AddChar(const unsigned int unicode, float advance, CharPos plane, CharUV atlas)
|
||||
{
|
||||
this->Chars[unicode] = Char(unicode, advance, plane, atlas);
|
||||
}
|
||||
|
||||
Char GetChar(unsigned int unicode)
|
||||
{
|
||||
if (Chars.find(unicode) != Chars.end())
|
||||
return Chars[unicode];
|
||||
return Char();
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> mAtlas;
|
||||
private:
|
||||
std::string mFilePath;
|
||||
msdfgen::FontHandle* mFontHandle;
|
||||
msdfgen::FreetypeHandle* mFreeTypeHandle;
|
||||
|
||||
std::map<unsigned int, Char> Chars;
|
||||
|
||||
|
||||
bool Load(const std::string& path);
|
||||
};
|
||||
}
|
||||
171
Nuake/src/UI/Font/FontLoader.h
Normal file
171
Nuake/src/UI/Font/FontLoader.h
Normal file
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
#include "Font.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <src/Rendering/Textures/Texture.h>
|
||||
|
||||
#include <Dependencies/msdf-atlas-gen/msdfgen/core/BitmapRef.hpp>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
// Config used by the atlas generator.
|
||||
struct Config
|
||||
{
|
||||
msdf_atlas::ImageType imageType;
|
||||
msdf_atlas::ImageFormat imageFormat;
|
||||
msdf_atlas::YDirection yDirection;
|
||||
int width, height;
|
||||
double emSize;
|
||||
double pxRange;
|
||||
double angleThreshold;
|
||||
double miterLimit;
|
||||
void (*edgeColoring)(msdfgen::Shape&, double, unsigned long long);
|
||||
bool expensiveColoring;
|
||||
unsigned long long coloringSeed;
|
||||
msdf_atlas::GeneratorAttributes generatorAttributes;
|
||||
bool preprocessGeometry;
|
||||
bool kerning;
|
||||
int threadCount = 1;
|
||||
};
|
||||
|
||||
|
||||
class FontLoader
|
||||
{
|
||||
public:
|
||||
static FontLoader& Get()
|
||||
{
|
||||
static FontLoader fontloader;
|
||||
return fontloader;
|
||||
}
|
||||
|
||||
template <typename T, typename S, int N, msdf_atlas::GeneratorFunction<S, N> GEN_FN>
|
||||
static bool makeAtlas(const std::vector<msdf_atlas::GlyphGeometry>& glyphs,
|
||||
const std::vector<msdf_atlas::FontGeometry>& fonts,
|
||||
Config& config, std::shared_ptr<Font> font) {
|
||||
// Create generator
|
||||
msdf_atlas::ImmediateAtlasGenerator<S, N, GEN_FN, msdf_atlas::BitmapAtlasStorage<T, N> > generator(config.width, config.height);
|
||||
|
||||
// Setup generator settings
|
||||
generator.setAttributes(config.generatorAttributes);
|
||||
generator.setThreadCount(config.threadCount);
|
||||
generator.generate(glyphs.data(), (int)glyphs.size());
|
||||
|
||||
// Create bitmap
|
||||
msdfgen::BitmapConstRef<T, N> bitmap = (msdfgen::BitmapConstRef<T, N>) generator.atlasStorage();
|
||||
|
||||
// Creat1e Texture from bitmap
|
||||
//msdf_atlas::exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.yDirection, "yayayayya.json", config.kerning);
|
||||
font->mAtlas = std::make_shared<Texture>(Vector2(config.width, config.height), (void*)bitmap.pixels);
|
||||
|
||||
// Create Char structure
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Font> LoadFont(const std::string& path)
|
||||
{
|
||||
auto font = Font::New(path);
|
||||
|
||||
// Create atlas settings
|
||||
Config config{};
|
||||
config.pxRange = 3;
|
||||
config.emSize = 0.0;
|
||||
config.coloringSeed = 125155;
|
||||
config.imageType = msdf_atlas::ImageType::MTSDF;
|
||||
config.imageFormat = msdf_atlas::ImageFormat::UNSPECIFIED;
|
||||
config.yDirection = msdf_atlas::YDirection::BOTTOM_UP;
|
||||
config.edgeColoring = msdfgen::edgeColoringInkTrap;
|
||||
config.kerning = true;
|
||||
config.preprocessGeometry = false;
|
||||
config.angleThreshold = 3.0;
|
||||
config.miterLimit = 1.0;
|
||||
config.generatorAttributes.scanlinePass = true;
|
||||
config.generatorAttributes.config.overlapSupport = true;
|
||||
|
||||
// Load charset ASCII
|
||||
std::vector<msdf_atlas::GlyphGeometry> glyphs;
|
||||
std::vector<msdf_atlas::FontGeometry> fonts;
|
||||
msdf_atlas::FontGeometry fontGeometry(&glyphs);
|
||||
msdf_atlas::Charset charset = msdf_atlas::Charset::ASCII;
|
||||
|
||||
// Load Create charset
|
||||
float fontScale = 36;
|
||||
|
||||
bool preprocess = false;
|
||||
int loaded = fontGeometry.loadCharset(font->GetFontHandle(), fontScale, charset, config.preprocessGeometry, config.kerning);
|
||||
fonts.push_back(fontGeometry);
|
||||
|
||||
if (glyphs.empty())
|
||||
{
|
||||
printf("Critical, Could not load font! \n");
|
||||
}
|
||||
|
||||
// Create atlas params
|
||||
msdf_atlas::TightAtlasPacker::DimensionsConstraint atlasSizeConstraint = msdf_atlas::TightAtlasPacker::DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE;
|
||||
msdf_atlas::TightAtlasPacker atlasPacker;
|
||||
atlasPacker.setDimensionsConstraint(atlasSizeConstraint);
|
||||
msdf_atlas::ImageType imageType = msdf_atlas::ImageType::MTSDF;
|
||||
atlasPacker.setPadding(imageType == msdf_atlas::ImageType::MSDF || imageType == msdf_atlas::ImageType::MTSDF ? 0 : -1);
|
||||
atlasPacker.setPixelRange(config.pxRange);
|
||||
atlasPacker.setUnitRange(config.emSize);
|
||||
atlasPacker.setMiterLimit(config.miterLimit);
|
||||
|
||||
// Pack atlas
|
||||
if (int remaining = atlasPacker.pack(glyphs.data(), (int)glyphs.size())) {
|
||||
if (remaining < 0) {
|
||||
printf("Critial - Failed to pack atlas");
|
||||
}
|
||||
else {
|
||||
printf("Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int)glyphs.size());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// update atlast size
|
||||
atlasPacker.getDimensions(config.width, config.height);
|
||||
if (!(config.width > 0 && config.height > 0))
|
||||
printf("Unable to determine atlas size.");
|
||||
|
||||
config.emSize = atlasPacker.getScale();
|
||||
config.pxRange = atlasPacker.getPixelRange();
|
||||
|
||||
// Color the glyph
|
||||
//unsigned long long glyphSeed = config.coloringSeed;
|
||||
//for (msdf_atlas::GlyphGeometry& glyph : glyphs) {
|
||||
// glyphSeed *= 6364136223846793005ull;
|
||||
// glyph.edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed);
|
||||
//}
|
||||
|
||||
msdf_atlas::Workload([&glyphs, &config](int i, int threadNo) -> bool {
|
||||
unsigned long long glyphSeed = (6364136223846793005ull * (config.coloringSeed ^ i) + 1442695040888963407ull) * !!config.coloringSeed;
|
||||
glyphs[i].edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed);
|
||||
return true;
|
||||
}, (int)glyphs.size()).finish(config.threadCount);
|
||||
|
||||
// Create bitmap and char structure
|
||||
auto bitmap = makeAtlas<byte, float, 4, msdf_atlas::mtsdfGenerator>(glyphs, fonts, config, font);
|
||||
|
||||
for (auto& g : glyphs)
|
||||
{
|
||||
CharPos plane = {};
|
||||
g.getQuadPlaneBounds(plane.left, plane.bottom, plane.right, plane.top);
|
||||
|
||||
CharUV box = {};
|
||||
|
||||
double x2, y2, z2, w2;
|
||||
g.getQuadAtlasBounds(x2, y2, z2, w2);
|
||||
box.Pos.x = (float)x2;
|
||||
box.Pos.y = (float)y2;
|
||||
box.Size.x = (float)z2;
|
||||
box.Size.y = (float)w2;
|
||||
font->AddChar(g.getCodepoint(), (float)g.getAdvance(), plane, box);
|
||||
}
|
||||
|
||||
return font;
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
18
Nuake/src/UI/Font/FontManager.cpp
Normal file
18
Nuake/src/UI/Font/FontManager.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "FontManager.h"
|
||||
#include "FontLoader.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<Font> FontManager::GetFont(const std::string& font)
|
||||
{
|
||||
if (mFonts.find(font) == mFonts.end())
|
||||
{
|
||||
mFonts[font] = FontLoader::Get().LoadFont(font);
|
||||
return mFonts[font];
|
||||
}
|
||||
else
|
||||
{
|
||||
return mFonts[font];
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Nuake/src/UI/Font/FontManager.h
Normal file
26
Nuake/src/UI/Font/FontManager.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "Font.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class FontManager
|
||||
{
|
||||
private:
|
||||
std::map<std::string, std::shared_ptr<Font>> mFonts;
|
||||
public:
|
||||
static FontManager& Get() {
|
||||
static FontManager fontManager;
|
||||
return fontManager;
|
||||
}
|
||||
|
||||
FontManager() {
|
||||
mFonts = std::map<std::string, std::shared_ptr<Font>>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Font> GetFont(const std::string& font);
|
||||
};
|
||||
}
|
||||
11
Nuake/src/UI/IController.h
Normal file
11
Nuake/src/UI/IController.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class IController
|
||||
{
|
||||
public:
|
||||
virtual void OnRegister() = 0;
|
||||
virtual void OnUnregister() = 0;
|
||||
};
|
||||
}
|
||||
8
Nuake/src/UI/InputManager.cpp
Normal file
8
Nuake/src/UI/InputManager.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "InputManager.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
float InputManager::ScrollX = 0.f;
|
||||
float InputManager::ScrollY = 0.f;
|
||||
std::stack<std::string> InputManager::InputStack = std::stack<std::string>();
|
||||
}
|
||||
31
Nuake/src/UI/InputManager.h
Normal file
31
Nuake/src/UI/InputManager.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class InputManager
|
||||
{
|
||||
public:
|
||||
static std::stack<std::string> InputStack;
|
||||
|
||||
static float ScrollX;
|
||||
static float ScrollY;
|
||||
|
||||
virtual bool IsMouseInputDown() = 0;
|
||||
virtual float GetMouseX() = 0;
|
||||
virtual float GetMouseY() = 0;
|
||||
|
||||
virtual float GetScrollX() = 0;
|
||||
virtual float GetScrollY() = 0;
|
||||
|
||||
virtual bool IsKeyPressed(uint32_t key) = 0;
|
||||
|
||||
static std::string ConsumeStack()
|
||||
{
|
||||
std::string item = InputStack.top();
|
||||
InputStack.pop();
|
||||
return item;
|
||||
}
|
||||
};
|
||||
}
|
||||
224
Nuake/src/UI/Inspector.h
Normal file
224
Nuake/src/UI/Inspector.h
Normal file
@@ -0,0 +1,224 @@
|
||||
#pragma once
|
||||
#include "Nodes/Canvas.h"
|
||||
#include "Nodes/Text.h"
|
||||
#include "Styles/StyleSheet.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Dependencies/NuakeRenderer/NuakeRenderer/NuakeRenderer.h>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<Node> mSelectedNode;
|
||||
|
||||
void DrawUI(std::shared_ptr<Node> node)
|
||||
{
|
||||
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_FramePadding |
|
||||
ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
// Highlight the selected node using a flag.
|
||||
if (mSelectedNode == node)
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
// Appends the classes of the node next to the name
|
||||
// Logic is only add [] if theres is a class and only add commans in between.
|
||||
std::string nodeTitle = node->GetID();
|
||||
nodeTitle = nodeTitle == "" ? node->GetType() : nodeTitle;
|
||||
const int classAmount = node->Classes.size();
|
||||
if (classAmount > 0)
|
||||
{
|
||||
nodeTitle += "[";
|
||||
for (int i = 0; i < classAmount; i++)
|
||||
{
|
||||
nodeTitle += node->Classes[i];
|
||||
|
||||
if (i < classAmount - 1)
|
||||
nodeTitle += ", ";
|
||||
}
|
||||
nodeTitle += "]";
|
||||
}
|
||||
|
||||
const bool nodeOpen = ImGui::TreeNodeEx(nodeTitle.c_str(), base_flags);
|
||||
|
||||
// Select the if clicked
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
mSelectedNode = node;
|
||||
}
|
||||
|
||||
// Draw the rest of th nodes recursively.
|
||||
if (nodeOpen)
|
||||
{
|
||||
for (auto& c : node->GetChildrens())
|
||||
DrawUI(c);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawNodeEditor()
|
||||
{
|
||||
if (!mSelectedNode)
|
||||
{
|
||||
ImGui::Text("No node selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto type = mSelectedNode->GetType();
|
||||
|
||||
ImGui::SliderFloat("Width", &mSelectedNode->ComputedStyle.Width.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Height", &mSelectedNode->ComputedStyle.Height.value, 0.0f, 1080.0f);
|
||||
ImGui::SliderFloat("Max Width", &mSelectedNode->ComputedStyle.MaxWidth.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Max Height", &mSelectedNode->ComputedStyle.MaxHeight.value, 0.0f, 1080.0f);
|
||||
ImGui::SliderFloat("Min Width", &mSelectedNode->ComputedStyle.MinWidth.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Min Height", &mSelectedNode->ComputedStyle.MinHeight.value, 0.0f, 1080.0f);
|
||||
|
||||
ImGui::SliderFloat("Padding Left", &mSelectedNode->ComputedStyle.PaddingLeft.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Padding Right", &mSelectedNode->ComputedStyle.PaddingRight.value, 0.0f, 1080.0f);
|
||||
ImGui::SliderFloat("Padding Top", &mSelectedNode->ComputedStyle.PaddingTop.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Padding Bottom", &mSelectedNode->ComputedStyle.PaddingBottom.value, 0.0f, 1080.0f);
|
||||
|
||||
ImGui::SliderFloat("Margin Left", &mSelectedNode->ComputedStyle.MarginLeft.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Margin Right", &mSelectedNode->ComputedStyle.MarginRight.value, 0.0f, 1080.0f);
|
||||
ImGui::SliderFloat("Margin Top", &mSelectedNode->ComputedStyle.MarginTop.value, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Margin Bottom", &mSelectedNode->ComputedStyle.MarginBottom.value, 0.0f, 1080.0f);
|
||||
|
||||
ImGui::SliderFloat("Flex Basis", &mSelectedNode->ComputedStyle.FlexBasis, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Flex Grow", &mSelectedNode->ComputedStyle.FlexGrow, 0.0f, 1080.0f);
|
||||
ImGui::SliderFloat("Flex Shrink", &mSelectedNode->ComputedStyle.FlexShrink, 0.f, 1920.0f);
|
||||
ImGui::SliderFloat("Font Size", &mSelectedNode->ComputedStyle.FontSize, 0.0f, 1080.0f);
|
||||
|
||||
ImGui::ColorEdit4("Background Color", (float*) &mSelectedNode->ComputedStyle.BackgroundColor);
|
||||
ImGui::DragFloat("Border Size", &mSelectedNode->ComputedStyle.BorderSize, 1.f, 0.f);
|
||||
ImGui::ColorEdit4("Border Color", (float*)&mSelectedNode->ComputedStyle.BorderColor);
|
||||
ImGui::DragFloat("Font Size", &mSelectedNode->ComputedStyle.FontSize, 1.f, 0.f);
|
||||
ImGui::ColorEdit4("Font Color", (float*)&mSelectedNode->ComputedStyle.FontColor);
|
||||
}
|
||||
|
||||
static void DrawInspector(std::shared_ptr<Canvas> canvas)
|
||||
{
|
||||
NuakeRenderer::BeginImGuiFrame();
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
|
||||
if (ImGui::Begin("Inspector"))
|
||||
{
|
||||
if (ImGui::BeginTabBar("MyTabBar"))
|
||||
{
|
||||
if (ImGui::BeginTabItem("Tree"))
|
||||
{
|
||||
const float treeWidth = ImGui::GetWindowContentRegionWidth();
|
||||
const float availHeight = ImGui::GetContentRegionAvail().y;
|
||||
const ImVec2 size = ImVec2(treeWidth * 0.5f, availHeight);
|
||||
const ImVec2 size2 = ImVec2(treeWidth * 0.5f, availHeight);
|
||||
if (ImGui::BeginChild("Tree", size))
|
||||
{
|
||||
DrawUI(canvas->GetRoot());
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::BeginChild("Editor", size2))
|
||||
{
|
||||
DrawNodeEditor();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("StyleSheet"))
|
||||
{
|
||||
if (ImGui::BeginChild("StyleSheetEditor", ImGui::GetContentRegionAvail()))
|
||||
{
|
||||
auto styleSheet = canvas->GetStyleSheet();
|
||||
|
||||
int ri = 0;
|
||||
for (auto& r : styleSheet->Rules)
|
||||
{
|
||||
std::string imguiText = "";
|
||||
for (int s = 0; s < r.Selector.size(); s++)
|
||||
{
|
||||
std::string selectorText = "";
|
||||
|
||||
auto& selector = r.Selector[s];
|
||||
auto type = selector.Type;
|
||||
if (type == StyleSelectorType::Id)
|
||||
selectorText += "#";
|
||||
else if (type == StyleSelectorType::Class)
|
||||
selectorText += ".";
|
||||
|
||||
selectorText += selector.Value.c_str();
|
||||
|
||||
if (s < r.Selector.size() - 1)
|
||||
selectorText += ", ";
|
||||
|
||||
imguiText += selectorText;
|
||||
}
|
||||
|
||||
imguiText += " { ";
|
||||
ImGui::Text(imguiText.c_str());
|
||||
|
||||
ImGui::Indent(8.f);
|
||||
|
||||
// Now the properties!
|
||||
int i = 0;
|
||||
for (auto& rule : r.Properties)
|
||||
{
|
||||
// Name
|
||||
std::string propName = "UnknownProperty";
|
||||
|
||||
StyleProperties type = rule.first;
|
||||
if (type == StyleProperties::Width) propName = "width: ";
|
||||
else if (type == StyleProperties::Height) propName = "weight: ";
|
||||
else if (type == StyleProperties::MinWidth) propName = "min-width: ";
|
||||
else if (type == StyleProperties::MinHeight) propName = "min-height: ";
|
||||
else if (type == StyleProperties::MaxWidth) propName = "max-width: ";
|
||||
else if (type == StyleProperties::MaxHeight) propName = "max-height: ";
|
||||
else if (type == StyleProperties::BackgroundColor) propName = "BackgroundColor: ";
|
||||
|
||||
ImGui::Text(propName.c_str());
|
||||
ImGui::SameLine();
|
||||
|
||||
std::string valueText = "";
|
||||
|
||||
// value
|
||||
PropValue& value = rule.second;
|
||||
if (value.type == PropValueType::Percent)
|
||||
{
|
||||
valueText += std::to_string(value.value.Number);
|
||||
valueText += "\%;";
|
||||
}
|
||||
else if (value.type == PropValueType::Pixel)
|
||||
{
|
||||
valueText += std::to_string(value.value.Number);
|
||||
valueText += "px;";
|
||||
}
|
||||
else if (value.type == PropValueType::Color)
|
||||
{
|
||||
Color colorFloat = rule.second.value.Color / 255.f;
|
||||
ImGui::ColorEdit4(("##colorEdit" + std::to_string(ri) + propName + std::to_string(i)).c_str(), &colorFloat.r);
|
||||
rule.second.value.Color = colorFloat * 255.f;
|
||||
}
|
||||
else if (value.type == PropValueType::Auto)
|
||||
{
|
||||
valueText += "auto;";
|
||||
}
|
||||
i++;
|
||||
ImGui::Text(valueText.c_str());
|
||||
}
|
||||
ImGui::Indent(-8.f);
|
||||
ImGui::Text("}");
|
||||
ri++;
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
NuakeRenderer::EndImGuiFrame();
|
||||
}
|
||||
}
|
||||
49
Nuake/src/UI/Nodes/Button.cpp
Normal file
49
Nuake/src/UI/Nodes/Button.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "Button.h"
|
||||
#include "Text.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<Button> Button::New(const std::string& name, const std::string& label)
|
||||
{
|
||||
return std::make_shared<Button>(name, label);
|
||||
}
|
||||
|
||||
Button::Button(const std::string& name, const std::string& label) :
|
||||
Label(label)
|
||||
{
|
||||
ID = name;
|
||||
//InsertChild(Text::New(ID + "lbl", Label));
|
||||
}
|
||||
|
||||
void Button::UpdateInput(InputManager* inputManager)
|
||||
{
|
||||
float mx = inputManager->GetMouseX();
|
||||
float my = inputManager->GetMouseY();
|
||||
bool isHover = IsMouseHover(mx, my);
|
||||
if (isHover)
|
||||
{
|
||||
bool isMouseDown = inputManager->IsMouseInputDown();
|
||||
if (isMouseDown)
|
||||
{
|
||||
State = NodeState::Pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State == NodeState::Pressed && !isMouseDown)
|
||||
{
|
||||
// Calling the click callback.
|
||||
if (mHasCallback)
|
||||
ClickCallback(*this);
|
||||
}
|
||||
State = NodeState::Hover;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
State = NodeState::Idle;
|
||||
}
|
||||
|
||||
for (auto& c : Childrens)
|
||||
c->UpdateInput(inputManager);
|
||||
}
|
||||
}
|
||||
34
Nuake/src/UI/Nodes/Button.h
Normal file
34
Nuake/src/UI/Nodes/Button.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "../InputManager.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class Button;
|
||||
typedef std::shared_ptr<Button> ButtonPtr;
|
||||
class Button : public Node
|
||||
{
|
||||
private:
|
||||
bool mHasBeenClicked = false;
|
||||
bool mHasCallback = false;
|
||||
public:
|
||||
std::string Label = "";
|
||||
|
||||
Button(const std::string& name, const std::string& label);
|
||||
~Button() {};
|
||||
|
||||
static ButtonPtr New(const std::string& name, const std::string& label);
|
||||
|
||||
std::function<void(Button&)> ClickCallback;
|
||||
|
||||
void UpdateInput(InputManager* inputManager) override;
|
||||
|
||||
void SetClickCallback(std::function<void(Button&)> callback)
|
||||
{
|
||||
mHasCallback = true;
|
||||
ClickCallback = callback;
|
||||
}
|
||||
};
|
||||
}
|
||||
169
Nuake/src/UI/Nodes/Canvas.cpp
Normal file
169
Nuake/src/UI/Nodes/Canvas.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "Canvas.h"
|
||||
#include <yoga/Yoga.h>
|
||||
#include <yoga/YGConfig.h>
|
||||
|
||||
#include "../Renderer.h"
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
CanvasPtr Canvas::New()
|
||||
{
|
||||
return std::make_shared<Canvas>();
|
||||
}
|
||||
|
||||
Canvas::Canvas() : mInputManager(nullptr), mDirty(false)
|
||||
{
|
||||
mYogaConfig = YGConfigNew();
|
||||
}
|
||||
|
||||
Canvas::~Canvas()
|
||||
{
|
||||
YGConfigFree(mYogaConfig);
|
||||
if (mRootNode)
|
||||
{
|
||||
YGNodeFreeRecursive(mRootNode->GetYogaNode());
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::Tick()
|
||||
{
|
||||
if (!mRootNode)
|
||||
return;
|
||||
|
||||
mRootNode->UpdateInput(mInputManager);
|
||||
mRootNode->Tick(mInputManager);
|
||||
|
||||
mInputManager->ScrollX = 0.f;
|
||||
mInputManager->ScrollY = 0.f;
|
||||
}
|
||||
|
||||
void Canvas::Draw()
|
||||
{
|
||||
if (!mRootNode)
|
||||
return;
|
||||
|
||||
Renderer::Get().BeginDraw();
|
||||
Renderer::Get().DrawNode(mRootNode, 0);
|
||||
mRootNode->Draw(0);
|
||||
}
|
||||
|
||||
void Canvas::ComputeLayout(Vector2 size)
|
||||
{
|
||||
if (!mRootNode)
|
||||
return;
|
||||
|
||||
Renderer::Get().SetViewportSize(size);
|
||||
|
||||
float x, y;
|
||||
x = mInputManager->GetMouseX();
|
||||
y = mInputManager->GetMouseY();
|
||||
|
||||
auto root = mRootNode->GetYogaNode();
|
||||
|
||||
// Recompute the node tree.
|
||||
if (mDirty)
|
||||
ComputeStyle(mRootNode);
|
||||
|
||||
mRootNode->Calculate();
|
||||
|
||||
if (root)
|
||||
YGNodeCalculateLayout(root, size.x, size.y, YGDirectionLTR);
|
||||
}
|
||||
|
||||
void Canvas::ComputeStyle(NodePtr node)
|
||||
{
|
||||
for (auto& s : node->GetDataModelOperations())
|
||||
{
|
||||
if (s->Type != OperationType::IfClass)
|
||||
continue;
|
||||
|
||||
|
||||
if (auto dataModel = node->GetDataModel(); s->Compare(dataModel))
|
||||
{
|
||||
node->AddClass(s->ClassName);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->RemoveClass(s->ClassName);
|
||||
}
|
||||
}
|
||||
for (auto& rule : mStyleSheet->Rules)
|
||||
{
|
||||
bool respectSelector = true;
|
||||
|
||||
for (StyleSelector& selector : rule.Selector)
|
||||
{
|
||||
bool foundSelector = false;
|
||||
if (selector.Type == StyleSelectorType::Class)
|
||||
{
|
||||
for (auto& c : node->Classes)
|
||||
{
|
||||
if (c == selector.Value)
|
||||
foundSelector = true;
|
||||
}
|
||||
}
|
||||
else if (selector.Type == StyleSelectorType::Pseudo)
|
||||
{
|
||||
if (selector.Value == "hover" && node->State == NodeState::Hover)
|
||||
foundSelector = true;
|
||||
if (selector.Value == "active" && node->State == NodeState::Pressed)
|
||||
foundSelector = true;
|
||||
}
|
||||
else if (selector.Type == StyleSelectorType::Id)
|
||||
{
|
||||
if (node->GetID() == selector.Value)
|
||||
foundSelector = true;
|
||||
}
|
||||
else if (selector.Type == StyleSelectorType::Tag)
|
||||
{
|
||||
if (selector.Value == node->GetType())
|
||||
{
|
||||
foundSelector = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSelector)
|
||||
respectSelector = false;
|
||||
}
|
||||
|
||||
if (respectSelector)
|
||||
node->ApplyStyleProperties(rule.Properties);
|
||||
}
|
||||
|
||||
for (auto& c : node->GetChildrens())
|
||||
{
|
||||
ComputeStyle(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Getters & Setters
|
||||
NodePtr Canvas::GetRoot() const
|
||||
{
|
||||
return mRootNode;
|
||||
}
|
||||
|
||||
void Canvas::SetRoot(NodePtr root)
|
||||
{
|
||||
mRootNode = root;
|
||||
}
|
||||
|
||||
void Canvas::SetInputManager(InputManager* inputManager)
|
||||
{
|
||||
mInputManager = inputManager;
|
||||
}
|
||||
|
||||
StyleSheetPtr Canvas::GetStyleSheet() const
|
||||
{
|
||||
return mStyleSheet;
|
||||
}
|
||||
|
||||
void Canvas::SetStyleSheet(StyleSheetPtr styleSheet)
|
||||
{
|
||||
mDirty = true;
|
||||
mStyleSheet = styleSheet;
|
||||
}
|
||||
}
|
||||
55
Nuake/src/UI/Nodes/Canvas.h
Normal file
55
Nuake/src/UI/Nodes/Canvas.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "../InputManager.h"
|
||||
#include "../Styles/StyleSheet.h"
|
||||
|
||||
#include <src/Core/Maths.h>
|
||||
#include "yoga/YGConfig.h"
|
||||
#include <memory>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class Canvas;
|
||||
typedef std::shared_ptr<Canvas> CanvasPtr;
|
||||
|
||||
class Canvas
|
||||
{
|
||||
private:
|
||||
YGConfigRef mYogaConfig;
|
||||
|
||||
std::string mFilePath = "";
|
||||
|
||||
InputManager* mInputManager;
|
||||
StyleSheetPtr mStyleSheet;
|
||||
|
||||
NodePtr mRootNode;
|
||||
|
||||
bool mDirty;
|
||||
public:
|
||||
static CanvasPtr New();
|
||||
Canvas();
|
||||
~Canvas();
|
||||
|
||||
void Tick();
|
||||
void Draw();
|
||||
void ComputeLayout(Vector2 size);
|
||||
void ComputeStyle(NodePtr node);
|
||||
|
||||
NodePtr GetRoot() const;
|
||||
void SetRoot(NodePtr root);
|
||||
|
||||
void SetInputManager(InputManager* manager);
|
||||
|
||||
StyleSheetPtr GetStyleSheet() const;
|
||||
void SetStyleSheet(StyleSheetPtr stylesheet);
|
||||
|
||||
template<class T>
|
||||
bool FindNodeByID(const std::string& id, std::shared_ptr<T>& node)
|
||||
{
|
||||
if (!this->mRootNode->FindChildByID<T>(id, node))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
599
Nuake/src/UI/Nodes/Node.cpp
Normal file
599
Nuake/src/UI/Nodes/Node.cpp
Normal file
@@ -0,0 +1,599 @@
|
||||
#include "Node.h"
|
||||
#include "../Renderer.h"
|
||||
|
||||
#include "NodeState.h"
|
||||
#include "../StringHelper.h"
|
||||
|
||||
#include <nanosvg.h>
|
||||
#include <nanosvgrast.h>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
NodePtr Node::New(const std::string id, const std::string& value)
|
||||
{
|
||||
return std::make_shared<Node>(id, value);
|
||||
}
|
||||
|
||||
Node::Node(const std::string& id, const std::string& value) : ID(id)
|
||||
{
|
||||
InitializeNode();
|
||||
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirection::YGFlexDirectionColumn);
|
||||
}
|
||||
|
||||
std::string Node::GetID() const
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
|
||||
uint32_t Node::GetIndex() const
|
||||
{
|
||||
if (!Parent)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
for (auto& c : Parent->GetChildrens())
|
||||
{
|
||||
if (c->mNode == mNode)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
YGNodeRef Node::GetYogaNode() const
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
std::string Node::GetType() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
void Node::InitializeNode()
|
||||
{
|
||||
if (mHasBeenInitialized)
|
||||
return;
|
||||
|
||||
mNode = YGNodeNew();
|
||||
Childrens = std::vector<NodePtr>();
|
||||
mHasBeenInitialized = true;
|
||||
}
|
||||
|
||||
bool Node::HasBeenInitialized() const
|
||||
{
|
||||
return mHasBeenInitialized;
|
||||
}
|
||||
|
||||
bool Node::HasDataModel() const
|
||||
{
|
||||
return mDataModel != nullptr;
|
||||
}
|
||||
|
||||
DataModelPtr Node::GetDataModel() const
|
||||
{
|
||||
if (HasDataModel())
|
||||
{
|
||||
return mDataModel;
|
||||
}
|
||||
|
||||
// Ask parent if they have a data model
|
||||
if (Parent != nullptr)
|
||||
{
|
||||
return Parent->GetDataModel();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Node::SetDataModel(const DataModelPtr& dataModel)
|
||||
{
|
||||
mDataModel = dataModel;
|
||||
}
|
||||
|
||||
float Node::GetScroll() const
|
||||
{
|
||||
return ScrollDelta;
|
||||
}
|
||||
|
||||
DataModelOperationCollection& Node::GetDataModelOperations()
|
||||
{
|
||||
return mDataModelOperations;
|
||||
}
|
||||
|
||||
void Node::AddDataModelOperation(DataModelOperationPtr& operation)
|
||||
{
|
||||
mDataModelOperations.push_back(operation);
|
||||
}
|
||||
|
||||
void Node::Tick(InputManager* inputManager)
|
||||
{
|
||||
OnTick(inputManager);
|
||||
|
||||
for (auto& c : Childrens)
|
||||
{
|
||||
c->Tick(inputManager);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::UpdateInput(InputManager* inputManager)
|
||||
{
|
||||
inputManager = inputManager;
|
||||
|
||||
float mx = inputManager->GetMouseX();
|
||||
float my = inputManager->GetMouseY();
|
||||
bool isHover = IsMouseHover(mx, my);
|
||||
|
||||
bool isMouseDown = inputManager->IsMouseInputDown();
|
||||
if (State == NodeState::Clicked && !isMouseDown)
|
||||
{
|
||||
State = NodeState::Hover;
|
||||
OnClickReleased(inputManager);
|
||||
}
|
||||
|
||||
if (!isMouseDown)
|
||||
{
|
||||
if (!isHover)
|
||||
{
|
||||
if (State != NodeState::Idle)
|
||||
{
|
||||
OnMouseExit(inputManager);
|
||||
}
|
||||
|
||||
State = NodeState::Idle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State != NodeState::Hover)
|
||||
{
|
||||
OnMouseHover(inputManager);
|
||||
}
|
||||
|
||||
State = NodeState::Hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Grab focus
|
||||
if (isHover && isMouseDown && State != NodeState::Clicked)
|
||||
{
|
||||
OnClick(inputManager);
|
||||
State = NodeState::Clicked;
|
||||
|
||||
if (CanGrabFocus)
|
||||
{
|
||||
GrabFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// Release focus
|
||||
if (!isHover && isMouseDown && State != NodeState::Clicked)
|
||||
{
|
||||
if (HasFocus())
|
||||
{
|
||||
ReleaseFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total absolute height of all the childrens
|
||||
float totalHeight = 0.0f;
|
||||
for (const auto& c : Childrens)
|
||||
{
|
||||
float childrenBottom = c->ComputedPosition.y + ScrollDelta + c->ComputedSize.y;
|
||||
if (childrenBottom > totalHeight)
|
||||
{
|
||||
totalHeight = childrenBottom;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate Max Scroll delta
|
||||
float maxScrollDelta = 0.f;
|
||||
if (totalHeight > ComputedSize.y)
|
||||
{
|
||||
maxScrollDelta = -(ComputedSize.y - totalHeight);
|
||||
}
|
||||
|
||||
// Scroll the parent and keep the remainder.
|
||||
float scroll = inputManager->GetScrollY();
|
||||
|
||||
bool isScrolled = std::abs(scroll) > 0.0f;
|
||||
bool canScroll = ComputedStyle.Overflow == OverflowType::Scroll;
|
||||
if (isScrolled && canScroll && isHover)
|
||||
{
|
||||
// Call node event
|
||||
OnScroll(inputManager);
|
||||
|
||||
const float SCROLL_FORCE = 40.f;
|
||||
const float scrollAmount = scroll * -SCROLL_FORCE;
|
||||
const float newDelta = ScrollDelta + scrollAmount;
|
||||
|
||||
// This is what remains of the scrolling if we hit the limits to resolve to parent.
|
||||
float remainder = 0.0f;
|
||||
if (scrollAmount > .0f)
|
||||
{
|
||||
if (ScrollDelta < maxScrollDelta && newDelta >= maxScrollDelta)
|
||||
{
|
||||
remainder = newDelta + maxScrollDelta;
|
||||
inputManager->ScrollY += scroll;
|
||||
ScrollDelta = maxScrollDelta;
|
||||
}
|
||||
else if (newDelta <= maxScrollDelta)
|
||||
{
|
||||
ScrollDelta = newDelta;
|
||||
inputManager->ScrollY += scroll;
|
||||
}
|
||||
}
|
||||
else if(scrollAmount < .0f)
|
||||
{
|
||||
if(ScrollDelta > 0.f && newDelta <= 0.f)
|
||||
{
|
||||
remainder = newDelta + maxScrollDelta;
|
||||
inputManager->ScrollY += scroll;
|
||||
ScrollDelta = 0.f;
|
||||
}
|
||||
else if (newDelta >= 0.f)
|
||||
{
|
||||
ScrollDelta = newDelta;
|
||||
inputManager->ScrollY += scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ScrollDelta > maxScrollDelta)
|
||||
{
|
||||
ScrollDelta = maxScrollDelta;
|
||||
}
|
||||
|
||||
for (auto& c : Childrens)
|
||||
{
|
||||
c->UpdateInput(inputManager);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Draw(int z)
|
||||
{
|
||||
z++;
|
||||
ComputedZIndex = ComputedStyle.ZIndex + z;
|
||||
if (ComputedStyle.Visibility == VisibilityType::Hidden)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const NodePtr& c : Childrens)
|
||||
{
|
||||
bool failedOperation = false;
|
||||
for (const auto& modelOp : c->GetDataModelOperations())
|
||||
{
|
||||
if (modelOp->Type == OperationType::If)
|
||||
{
|
||||
const DataModelPtr& model = c->GetDataModel();
|
||||
if (model && !modelOp->Compare(model))
|
||||
{
|
||||
failedOperation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isHidden = c->ComputedStyle.Visibility == VisibilityType::Hidden;
|
||||
if (isHidden || failedOperation)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Renderer::Get().DrawNode(c, ComputedZIndex);
|
||||
c->Draw(ComputedZIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Calculate()
|
||||
{
|
||||
for (auto& c : Childrens)
|
||||
{
|
||||
c->Calculate();
|
||||
}
|
||||
}
|
||||
|
||||
bool Node::IsMouseHover(float x, float y)
|
||||
{
|
||||
YGNodeRef ygNode = GetYogaNode();
|
||||
|
||||
float parentScroll = 0.f;
|
||||
if (Parent)
|
||||
parentScroll = Parent->ScrollDelta;
|
||||
|
||||
float width = YGNodeLayoutGetWidth(ygNode);
|
||||
float height = YGNodeLayoutGetHeight(ygNode);
|
||||
float padding = YGNodeLayoutGetPadding(ygNode, YGEdgeLeft);
|
||||
float left = YGNodeLayoutGetLeft(ygNode);
|
||||
float top = YGNodeLayoutGetTop(ygNode) - parentScroll;
|
||||
|
||||
float parentLeft = 0.0f;
|
||||
float parentTop = 0.0f;
|
||||
|
||||
auto parent = Parent;
|
||||
if (parent)
|
||||
{
|
||||
parentLeft = parent->ComputedPosition.x;
|
||||
parentTop = parent->ComputedPosition.y;
|
||||
}
|
||||
|
||||
left += parentLeft;
|
||||
top += parentTop;
|
||||
bool isHover = x > left && x < left + width && y > top && y < top + height;
|
||||
return isHover;
|
||||
}
|
||||
|
||||
void Node::InsertChild(NodePtr child)
|
||||
{
|
||||
if (!mHasBeenInitialized)
|
||||
InitializeNode();
|
||||
|
||||
child->Parent = this;
|
||||
Childrens.push_back(child);
|
||||
uint32_t index = (uint32_t)Childrens.size() - 1;
|
||||
YGNodeInsertChild(this->mNode, child->GetYogaNode(), index);
|
||||
}
|
||||
|
||||
Node* Node::mFocused = nullptr;
|
||||
void Node::GrabFocus()
|
||||
{
|
||||
mFocused = this;
|
||||
}
|
||||
|
||||
bool Node::HasFocus() const
|
||||
{
|
||||
return mFocused == this;
|
||||
}
|
||||
|
||||
void Node::ReleaseFocus()
|
||||
{
|
||||
mFocused = nullptr;
|
||||
}
|
||||
|
||||
void Node::ApplyStyleProperties(std::map<StyleProperties, PropValue> properties)
|
||||
{
|
||||
for (auto& p : properties)
|
||||
{
|
||||
StyleProperties prop = p.first;
|
||||
PropValue value = p.second;
|
||||
|
||||
switch (prop)
|
||||
{
|
||||
LengthProp(Width)
|
||||
LengthProp(Height)
|
||||
LengthProp(MinHeight)
|
||||
LengthProp(MinWidth)
|
||||
LengthProp(MaxHeight)
|
||||
LengthProp(MaxWidth)
|
||||
LengthProp(MarginLeft)
|
||||
LengthProp(MarginTop)
|
||||
LengthProp(MarginRight)
|
||||
LengthProp(MarginBottom)
|
||||
LengthProp(PaddingLeft)
|
||||
LengthProp(PaddingTop)
|
||||
LengthProp(PaddingRight)
|
||||
LengthProp(PaddingBottom)
|
||||
case StyleProperties::Top:
|
||||
ComputedStyle.Top = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::Bottom:
|
||||
ComputedStyle.Bottom = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::Left:
|
||||
ComputedStyle.Left = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::Right:
|
||||
ComputedStyle.Right = value.value.Number;
|
||||
break;
|
||||
EnumProp(Position)
|
||||
EnumProp(AlignItems)
|
||||
EnumPropEx(SelfAlign, AlignItemsType)
|
||||
case StyleProperties::AspectRatio:
|
||||
ComputedStyle.AspectRatio = value.value.Number;
|
||||
break;
|
||||
EnumProp(FlexDirection)
|
||||
EnumProp(FlexWrap)
|
||||
case StyleProperties::FlexBasis:
|
||||
ComputedStyle.FlexBasis = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::FlexGrow:
|
||||
ComputedStyle.FlexGrow = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::FlexShrink:
|
||||
ComputedStyle.FlexShrink = value.value.Number;
|
||||
break;
|
||||
EnumProp(JustifyContent)
|
||||
EnumProp(AlignContent)
|
||||
EnumProp(LayoutDirection)
|
||||
case StyleProperties::BorderSize:
|
||||
ComputedStyle.BorderSize = std::clamp(value.value.Number, 0.f, ComputedSize.x / 2.0f);
|
||||
break;
|
||||
case StyleProperties::BorderRadius:
|
||||
ComputedStyle.BorderRadius = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::BorderColor:
|
||||
ComputedStyle.BorderColor = value.value.Color / 255.f;
|
||||
break;
|
||||
case StyleProperties::BackgroundColor:
|
||||
this->ComputedStyle.BackgroundColor = value.value.Color / 255.f;
|
||||
break;
|
||||
case StyleProperties::Color:
|
||||
ComputedStyle.FontColor = value.value.Color / 255.f;
|
||||
break;
|
||||
case StyleProperties::TextAlign:
|
||||
ComputedStyle.TextAlign = (TextAlignType)(value.value.Enum);
|
||||
break;
|
||||
case StyleProperties::Overflow:
|
||||
ComputedStyle.Overflow = (OverflowType)value.value.Enum;
|
||||
break;
|
||||
case StyleProperties::FontSize:
|
||||
ComputedStyle.FontSize = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::Visibility:
|
||||
ComputedStyle.Visibility = (VisibilityType)value.value.Enum;
|
||||
break;
|
||||
case StyleProperties::ZIndex:
|
||||
ComputedStyle.ZIndex = value.value.Number;
|
||||
break;
|
||||
case StyleProperties::BackgroundImage:
|
||||
{
|
||||
if (ComputedStyle.BackgroundImage == nullptr)
|
||||
{
|
||||
if (StringHelper::EndsWith(value.string, ".svg"))
|
||||
{
|
||||
//NSVGimage* image = NULL;
|
||||
//NSVGrasterizer* rast = NULL;
|
||||
//unsigned char* img = NULL;
|
||||
//
|
||||
//int w, h;
|
||||
//image = nsvgParseFromFile(value.string.c_str(), "px", 96.0f);
|
||||
//if (image == NULL) {
|
||||
// printf("Could not open SVG image.\n");
|
||||
//
|
||||
//}
|
||||
//w = (int)image->width;
|
||||
//h = (int)image->height;
|
||||
//
|
||||
//rast = nsvgCreateRasterizer();
|
||||
//if (rast == NULL) {
|
||||
// printf("Could not init rasterizer.\n");
|
||||
//}
|
||||
//
|
||||
//img = (unsigned char*)malloc(w * h * 4);
|
||||
//if (img == NULL) {
|
||||
// printf("Could not alloc image buffer.\n");
|
||||
//}
|
||||
//
|
||||
//nsvgRasterize(rast, image, 0, 0, 1, img, w, h, w * 4);
|
||||
//
|
||||
//auto texture = std::make_shared<Texture>(img, w * h * 4);
|
||||
//ComputedStyle.BackgroundImage = texture;
|
||||
//
|
||||
//nsvgDeleteRasterizer(rast);
|
||||
//nsvgDelete(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto texture = std::make_shared<Texture>(value.string);
|
||||
ComputedStyle.BackgroundImage = texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetLength(Width)
|
||||
SetLength(Height)
|
||||
|
||||
if (ComputedStyle.Position == PositionType::Absolute)
|
||||
{
|
||||
if (ComputedStyle.Top != -1)
|
||||
{
|
||||
YGNodeStyleSetPosition(mNode, YGEdgeTop, ComputedStyle.Top);
|
||||
}
|
||||
if (ComputedStyle.Bottom != -1)
|
||||
{
|
||||
YGNodeStyleSetPosition(mNode, YGEdgeBottom, ComputedStyle.Bottom);
|
||||
}
|
||||
if (ComputedStyle.Left != -1)
|
||||
{
|
||||
YGNodeStyleSetPosition(mNode, YGEdgeLeft, ComputedStyle.Left);
|
||||
}
|
||||
if (ComputedStyle.Right != -1)
|
||||
{
|
||||
YGNodeStyleSetPosition(mNode, YGEdgeRight, ComputedStyle.Right);
|
||||
}
|
||||
}
|
||||
|
||||
SetLengthNoAuto(MaxWidth)
|
||||
SetLengthNoAuto(MaxHeight)
|
||||
SetLengthNoAuto(MinWidth)
|
||||
SetLengthNoAuto(MinHeight)
|
||||
SetLengthNoAuto(MaxWidth)
|
||||
SetLengthNoAuto(MaxHeight)
|
||||
SetLengthBorder(Margin, Left);
|
||||
SetLengthBorder(Margin, Top);
|
||||
SetLengthBorder(Margin, Right);
|
||||
SetLengthBorder(Margin, Bottom);
|
||||
SetLengthBorderNoAuto(Padding, Left);
|
||||
SetLengthBorderNoAuto(Padding, Top);
|
||||
SetLengthBorderNoAuto(Padding, Right);
|
||||
SetLengthBorderNoAuto(Padding, Bottom);
|
||||
|
||||
if (ComputedStyle.Position == PositionType::Relative)
|
||||
YGNodeStyleSetPositionType(mNode, YGPositionTypeRelative);
|
||||
else if (ComputedStyle.Position == PositionType::Absolute)
|
||||
YGNodeStyleSetPositionType(mNode, YGPositionTypeAbsolute);
|
||||
if (ComputedStyle.FlexDirection == FlexDirectionType::Column)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionColumn);
|
||||
else if (ComputedStyle.FlexDirection == FlexDirectionType::ColumnReversed)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionColumnReverse);
|
||||
else if (ComputedStyle.FlexDirection == FlexDirectionType::Row)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionRow);
|
||||
else if (ComputedStyle.FlexDirection == FlexDirectionType::RowReversed)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionRowReverse);
|
||||
|
||||
if (ComputedStyle.JustifyContent == JustifyContentType::FlexStart)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifyFlexStart);
|
||||
else if (ComputedStyle.JustifyContent == JustifyContentType::Center)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifyCenter);
|
||||
else if (ComputedStyle.JustifyContent == JustifyContentType::FlexEnd)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifyFlexEnd);
|
||||
else if (ComputedStyle.JustifyContent == JustifyContentType::SpaceAround)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifySpaceAround);
|
||||
else if (ComputedStyle.JustifyContent == JustifyContentType::SpaceBetween)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifySpaceBetween);
|
||||
else if (ComputedStyle.JustifyContent == JustifyContentType::SpaceEvenly)
|
||||
YGNodeStyleSetJustifyContent(mNode, YGJustifySpaceEvenly);
|
||||
|
||||
if (ComputedStyle.AlignItems == AlignItemsType::FlexStart)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignFlexStart);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Center)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignCenter);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::FlexEnd)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignFlexEnd);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::SpaceAround)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignSpaceAround);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::SpaceBetween)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignSpaceBetween);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Stretch)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignStretch);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Baseline)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignBaseline);
|
||||
|
||||
if (ComputedStyle.FlexDirection == FlexDirectionType::Row)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionRow);
|
||||
if (ComputedStyle.FlexDirection == FlexDirectionType::RowReversed)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionRowReverse);
|
||||
if (ComputedStyle.FlexDirection == FlexDirectionType::Column)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionColumn);
|
||||
if (ComputedStyle.FlexDirection == FlexDirectionType::ColumnReversed)
|
||||
YGNodeStyleSetFlexDirection(mNode, YGFlexDirectionColumnReverse);
|
||||
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Center)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignCenter);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::FlexEnd)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignFlexEnd);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::SpaceAround)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignSpaceAround);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::SpaceBetween)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignSpaceBetween);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Stretch)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignStretch);
|
||||
else if (ComputedStyle.AlignItems == AlignItemsType::Baseline)
|
||||
YGNodeStyleSetAlignItems(mNode, YGAlignBaseline);
|
||||
}
|
||||
|
||||
std::vector<NodePtr> Node::GetChildrens() const
|
||||
{
|
||||
return Childrens;
|
||||
}
|
||||
}
|
||||
240
Nuake/src/UI/Nodes/Node.h
Normal file
240
Nuake/src/UI/Nodes/Node.h
Normal file
@@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
#include "NodeState.h"
|
||||
|
||||
#include "../DataBinding/DataBindObject.h"
|
||||
#include "../DataBinding/DataModelOperations.h"
|
||||
|
||||
#include "../Styles/StyleSheet.h"
|
||||
#include "../Nodes/NodeStyle.h"
|
||||
|
||||
#include "../InputManager.h"
|
||||
|
||||
#include <src/Core/Maths.h>
|
||||
#include <yoga/yoga.h>
|
||||
|
||||
#include <any>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define SetLength(name) \
|
||||
if (ComputedStyle.##name.type == LengthType::Auto) \
|
||||
YGNodeStyleSet##name##Auto(mNode); \
|
||||
else if (ComputedStyle.##name.type == LengthType::Pixel) YGNodeStyleSet##name(mNode, ComputedStyle.##name.value); \
|
||||
else if (ComputedStyle.##name.type == LengthType::Percentage) YGNodeStyleSet##name##Percent(mNode, ComputedStyle.##name.value); \
|
||||
|
||||
#define SetLengthBorder(name, border) \
|
||||
if (ComputedStyle.##name##border.type == LengthType::Auto) \
|
||||
YGNodeStyleSet##name##Auto(mNode, YGEdge##border); \
|
||||
else if (ComputedStyle.##name##border.type == LengthType::Pixel) YGNodeStyleSet##name(mNode, YGEdge##border, ComputedStyle.##name##border.value); \
|
||||
else if (ComputedStyle.##name##border.type == LengthType::Percentage) YGNodeStyleSet##name##Percent(mNode, YGEdge##border, ComputedStyle.##name##border.value); \
|
||||
|
||||
#define SetLengthBorderNoAuto(name, border) \
|
||||
if (ComputedStyle.##name##border.type == LengthType::Pixel) YGNodeStyleSet##name(mNode, YGEdge##border, ComputedStyle.##name##border.value); \
|
||||
else if (ComputedStyle.##name##border.type == LengthType::Percentage) YGNodeStyleSet##name##Percent(mNode, YGEdge##border, ComputedStyle.##name##border.value); \
|
||||
|
||||
|
||||
#define SetLengthNoAuto(name) \
|
||||
if (ComputedStyle.##name.type == LengthType::Pixel) YGNodeStyleSet##name(mNode, ComputedStyle.##name.value); \
|
||||
else if (ComputedStyle.##name.type == LengthType::Percentage) YGNodeStyleSet##name##Percent(mNode, ComputedStyle.##name.value); \
|
||||
|
||||
#define EnumProp(name) EnumPropEx(name, ##name##Type)
|
||||
|
||||
#define EnumPropEx(name, enums) \
|
||||
case StyleProperties::name: \
|
||||
{ \
|
||||
auto type = value.value.Enum; \
|
||||
ComputedStyle.##name## = (##enums##)type; \
|
||||
} \
|
||||
break;\
|
||||
|
||||
#define LengthProp(name) \
|
||||
case StyleProperties::name: \
|
||||
{ \
|
||||
switch (value.type) \
|
||||
{ \
|
||||
case PropValueType::Pixel: \
|
||||
{ \
|
||||
ComputedStyle.name.type = LengthType::Pixel; \
|
||||
ComputedStyle.name.value = value.value.Number; \
|
||||
} \
|
||||
break; \
|
||||
case PropValueType::Percent: \
|
||||
{ \
|
||||
ComputedStyle.name.type = LengthType::Percentage; \
|
||||
ComputedStyle.name.value = value.value.Number; \
|
||||
} \
|
||||
break; \
|
||||
case PropValueType::Auto: \
|
||||
{ \
|
||||
ComputedStyle.name.type = LengthType::Auto; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class Node;
|
||||
typedef std::shared_ptr<Node> NodePtr;
|
||||
class Renderer;
|
||||
class CanvasParser;
|
||||
class Node
|
||||
{
|
||||
friend CanvasParser;
|
||||
friend Renderer;
|
||||
private:
|
||||
static Node* mFocused;
|
||||
|
||||
protected:
|
||||
float ScrollDelta = 0.0f;
|
||||
std::string ID = "";
|
||||
std::string Type = "node";
|
||||
Node* Parent = nullptr;
|
||||
std::vector<NodePtr> Childrens = std::vector<NodePtr>();
|
||||
|
||||
YGNodeRef mNode;
|
||||
|
||||
DataModelOperationCollection mDataModelOperations;
|
||||
DataModelPtr mDataModel;
|
||||
|
||||
bool mHasBeenInitialized = false;
|
||||
void InitializeNode();
|
||||
|
||||
public:
|
||||
bool CanGrabFocus = false;
|
||||
std::any UserData;
|
||||
NodeState State = NodeState::Idle;
|
||||
|
||||
std::vector<std::string> Classes = std::vector<std::string>();
|
||||
Vector2 ComputedSize = { 0, 0 };
|
||||
Vector2 ComputedPosition = { 0, 0 };
|
||||
int32_t ComputedZIndex = 0;
|
||||
NodeStyle ComputedStyle;
|
||||
|
||||
static NodePtr New(const std::string id, const std::string& value = "");
|
||||
Node(const std::string& id, const std::string& value = "");
|
||||
Node() = default;
|
||||
~Node() = default;
|
||||
|
||||
bool HasBeenInitialized() const;
|
||||
|
||||
virtual void Draw(int z);
|
||||
virtual void UpdateInput(InputManager* manager);
|
||||
virtual void Tick(InputManager* manager);
|
||||
virtual void Calculate();
|
||||
|
||||
virtual void OnMouseHover(InputManager* inputManager) {};
|
||||
virtual void OnMouseExit(InputManager* inputManager) {};
|
||||
virtual void OnClick(InputManager* inputManager) {};
|
||||
virtual void OnTick(InputManager* manager) {};
|
||||
virtual void OnClickReleased(InputManager* inputManager) {};
|
||||
virtual void OnScroll(InputManager* inputManager) {};
|
||||
|
||||
bool HasFocus() const;
|
||||
void GrabFocus();
|
||||
void ReleaseFocus();
|
||||
|
||||
void ApplyStyleProperties(std::map<StyleProperties, PropValue> properties);
|
||||
|
||||
void AddClass(const std::string& c)
|
||||
{
|
||||
bool containClass = false;
|
||||
for (auto& classe : Classes)
|
||||
{
|
||||
if (c == classe)
|
||||
{
|
||||
containClass = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containClass)
|
||||
{
|
||||
Classes.push_back(c);
|
||||
}
|
||||
}
|
||||
void RemoveClass(const std::string& c)
|
||||
{
|
||||
bool found = false;
|
||||
int i = 0;
|
||||
for (auto& cc : Classes)
|
||||
{
|
||||
if (cc == c)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if(found)
|
||||
Classes.erase(Classes.begin() + i);
|
||||
|
||||
}
|
||||
bool HasClass(const std::string& c) const
|
||||
{
|
||||
bool found = false;
|
||||
for (auto& cc : Classes)
|
||||
if (cc == c) found = true;
|
||||
return found;
|
||||
}
|
||||
|
||||
// Getter Setter
|
||||
std::string GetType() const;
|
||||
std::string GetID() const;
|
||||
uint32_t GetIndex() const;
|
||||
YGNodeRef GetYogaNode() const;
|
||||
float GetScroll() const;
|
||||
bool IsMouseHover(float x, float y);
|
||||
|
||||
bool HasDataModel() const;
|
||||
DataModelPtr GetDataModel() const;
|
||||
void SetDataModel(const DataModelPtr& dataModel);
|
||||
|
||||
DataModelOperationCollection& GetDataModelOperations();
|
||||
void AddDataModelOperation(DataModelOperationPtr& operation);
|
||||
|
||||
std::vector<NodePtr> GetChildrens() const;
|
||||
void InsertChild(NodePtr child);
|
||||
|
||||
template<class T>
|
||||
std::shared_ptr<T> GetChild(unsigned int index)
|
||||
{
|
||||
assert(index < Childrens.size()); // No childrens.
|
||||
return std::static_pointer_cast<T>(Childrens[index]);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::shared_ptr<T> GetChildByID(const std::string& id)
|
||||
{
|
||||
assert(Childrens.size() > 0); // No childrens.
|
||||
for (auto& c : Childrens)
|
||||
{
|
||||
if (c->ID == id)
|
||||
return std::static_pointer_cast<T>(c);
|
||||
}
|
||||
|
||||
assert(false); // Node not found.
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool FindChildByID(const std::string& id, std::shared_ptr<T>& node)
|
||||
{
|
||||
for (auto& c : Childrens)
|
||||
{
|
||||
if (c->ID == id)
|
||||
{
|
||||
node = std::static_pointer_cast<T>(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c->FindChildByID<T>(id, node))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
8
Nuake/src/UI/Nodes/NodeState.h
Normal file
8
Nuake/src/UI/Nodes/NodeState.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace NuakeUI {
|
||||
enum class NodeState
|
||||
{
|
||||
Idle, Hover, Pressed, Clicked
|
||||
};
|
||||
}
|
||||
66
Nuake/src/UI/Nodes/NodeStyle.h
Normal file
66
Nuake/src/UI/Nodes/NodeStyle.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
#include "../Styles/Style.h"
|
||||
|
||||
#include <src/Core/Maths.h>
|
||||
#include <src/Rendering/Textures/Texture.h>
|
||||
|
||||
using namespace Nuake;
|
||||
namespace NuakeUI
|
||||
{
|
||||
enum class LengthType
|
||||
{
|
||||
Percentage, Pixel, Auto
|
||||
};
|
||||
|
||||
struct Length
|
||||
{
|
||||
float value = 1.f;
|
||||
LengthType type = LengthType::Auto;
|
||||
};
|
||||
|
||||
struct NodeStyle
|
||||
{
|
||||
Color BackgroundColor = Color(0, 0, 0, 0);
|
||||
float BorderWidth = 0.f;
|
||||
Length Width;
|
||||
Length MinWidth;
|
||||
Length MaxWidth;
|
||||
Length Height;
|
||||
Length MinHeight;
|
||||
Length MaxHeight;
|
||||
Length PaddingLeft = { 0.f, LengthType::Pixel };
|
||||
Length PaddingTop = { 0.f, LengthType::Pixel };
|
||||
Length PaddingRight = { 0.f, LengthType::Pixel };
|
||||
Length PaddingBottom = { 0.f, LengthType::Pixel };
|
||||
Length MarginLeft = { 0.f, LengthType::Pixel };
|
||||
Length MarginTop = { 0.f, LengthType::Pixel };
|
||||
Length MarginRight = { 0.f, LengthType::Pixel };
|
||||
Length MarginBottom = { 0.f, LengthType::Pixel };
|
||||
PositionType Position = PositionType::Relative;
|
||||
AlignItemsType SelfAlign;
|
||||
AlignItemsType AlignItems;
|
||||
float AspectRatio;
|
||||
FlexDirectionType FlexDirection;
|
||||
FlexWrapType FlexWrap;
|
||||
float FlexBasis;
|
||||
float FlexGrow;
|
||||
float FlexShrink;
|
||||
JustifyContentType JustifyContent;
|
||||
AlignContentType AlignContent;
|
||||
LayoutDirectionType LayoutDirection;
|
||||
float BorderSize = 0.f;
|
||||
float BorderRadius = 0.f;
|
||||
Color BorderColor = Color(0, 0, 0, 0);
|
||||
float FontSize = 64.0f;
|
||||
TextAlignType TextAlign = TextAlignType::Left;
|
||||
Color FontColor = Color(1, 1, 1, 1);
|
||||
OverflowType Overflow = OverflowType::Show;
|
||||
VisibilityType Visibility = VisibilityType::Show;
|
||||
std::shared_ptr<Texture> BackgroundImage = nullptr;
|
||||
int32_t ZIndex = 0;
|
||||
float Top = -1;
|
||||
float Bottom = -1;
|
||||
float Right = -1;
|
||||
float Left = -1;
|
||||
};
|
||||
}
|
||||
139
Nuake/src/UI/Nodes/Text.cpp
Normal file
139
Nuake/src/UI/Nodes/Text.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "Text.h"
|
||||
|
||||
#include "../Renderer.h"
|
||||
|
||||
#include "src/Rendering/Renderer.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<Text> Text::New(const std::string& id, const std::string& text)
|
||||
{
|
||||
return std::make_shared<Text>(id, text);
|
||||
}
|
||||
|
||||
Text::Text(const std::string& id, const std::string& text)
|
||||
{
|
||||
ID = id;
|
||||
mNode = YGNodeNew();
|
||||
|
||||
mFont = Renderer::Get().mDefaultFont;
|
||||
|
||||
SetText(text);
|
||||
float height = ((mFont->LineHeight) / 32.f) * ComputedStyle.FontSize * Lines.size();
|
||||
YGNodeStyleSetHeight(mNode, height);
|
||||
YGNodeStyleSetMinHeight(mNode, height);
|
||||
YGNodeStyleSetMinWidth(mNode, CalculateWidth());
|
||||
YGNodeStyleSetWidthPercent(mNode, 100.f);
|
||||
}
|
||||
|
||||
void Text::SetText(const std::string& text)
|
||||
{
|
||||
Lines.clear();
|
||||
|
||||
// Split into lines
|
||||
auto ss = std::stringstream{ text };
|
||||
for (std::string line; std::getline(ss, line, '\n');)
|
||||
Lines.push_back(line);
|
||||
|
||||
if(std::size(Lines) > 0)
|
||||
Calculate();
|
||||
}
|
||||
|
||||
void Text::Draw(int z)
|
||||
{
|
||||
const float width = YGNodeLayoutGetWidth(mNode);
|
||||
const float height = YGNodeLayoutGetHeight(mNode);
|
||||
ComputedSize = { width, height };
|
||||
|
||||
float x = YGNodeLayoutGetLeft(mNode);
|
||||
float y = YGNodeLayoutGetTop(mNode);
|
||||
|
||||
// Centers the text in the line height.
|
||||
y += (mFont->LineHeight / 64.0f) * (ComputedStyle.FontSize) / 2.0f;
|
||||
|
||||
x += YGNodeLayoutGetPadding(mNode, YGEdgeLeft);
|
||||
y += YGNodeLayoutGetPadding(mNode, YGEdgeTop);
|
||||
|
||||
auto parent = Parent;
|
||||
bool hasParent = parent != nullptr;
|
||||
if (hasParent)
|
||||
{
|
||||
x += parent->ComputedPosition.x;
|
||||
y += parent->ComputedPosition.y - parent->GetScroll();
|
||||
}
|
||||
|
||||
Vector3 position = Vector3(x, y, z);
|
||||
ComputedPosition = position;
|
||||
|
||||
if (ComputedStyle.TextAlign == TextAlignType::Center)
|
||||
{ // We center the text horizontally.
|
||||
position.x += (width / 2.0f) - CalculateWidth() / 2.0f;
|
||||
}
|
||||
else if (ComputedStyle.TextAlign == TextAlignType::Right)
|
||||
{ // Aligns the line of the left
|
||||
position.x += width - CalculateWidth();
|
||||
}
|
||||
|
||||
// Scissor the parent bounding box.
|
||||
bool hideOverflow = hasParent && Parent->ComputedStyle.Overflow == OverflowType::Hidden;
|
||||
if (hideOverflow)
|
||||
{
|
||||
//glEnable(GL_SCISSOR_TEST);
|
||||
int clipX = (int)Parent->ComputedPosition.x;
|
||||
int clipY = (1080 - (int)Parent->ComputedPosition.y - (int)Parent->ComputedSize.y);
|
||||
int clipWidth = (int)Parent->ComputedSize.x;
|
||||
int clipHeight = (int)Parent->ComputedSize.y;
|
||||
//glScissor(clipX, clipY, clipWidth, clipHeight);
|
||||
}
|
||||
|
||||
const float lineYOffset = (mFont->LineHeight / 32.0f) * (ComputedStyle.FontSize);
|
||||
// Draw each line and offset the Y of the position by the line height.
|
||||
for(int i = 0; i < Lines.size(); i++)
|
||||
{
|
||||
// Draw the first line
|
||||
Renderer::Get().DrawString(Lines[i], ComputedStyle, mFont, position);
|
||||
// Update the Y position to the next line.
|
||||
position.y += lineYOffset;
|
||||
}
|
||||
|
||||
// Disable scissoring.
|
||||
if (hideOverflow){}
|
||||
//glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
float Text::CalculateWidth()
|
||||
{
|
||||
// If theres no text, then assume it's 0;
|
||||
if (Lines.size() == 0) return 0.f;
|
||||
|
||||
const float fontSize = ComputedStyle.FontSize / 64.f;
|
||||
|
||||
// Find the largest line.
|
||||
float maxWidth = 0.f;
|
||||
for (auto& l : Lines)
|
||||
{
|
||||
float textWidth = 0.f;
|
||||
// Iterate over each character and add up the advance.
|
||||
for (char const& c : l)
|
||||
{
|
||||
Char letter = mFont->GetChar((int)c);
|
||||
textWidth += (letter.Advance);
|
||||
}
|
||||
|
||||
if (textWidth > maxWidth)
|
||||
maxWidth = textWidth;
|
||||
}
|
||||
|
||||
// Scale the width by the font size.
|
||||
return maxWidth * fontSize;
|
||||
}
|
||||
|
||||
void Text::Calculate()
|
||||
{
|
||||
const float halfLineHeight = mFont->LineHeight / 32.f;
|
||||
const float linesHeight = Lines.size() * ComputedStyle.FontSize;
|
||||
YGNodeStyleSetHeight(mNode, halfLineHeight * linesHeight);
|
||||
YGNodeStyleSetWidth(mNode, CalculateWidth());
|
||||
}
|
||||
}
|
||||
32
Nuake/src/UI/Nodes/Text.h
Normal file
32
Nuake/src/UI/Nodes/Text.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "../Font/Font.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class Text;
|
||||
typedef std::shared_ptr<Text> TextPtr;
|
||||
|
||||
class Text : public Node
|
||||
{
|
||||
public:
|
||||
std::vector<std::string> Lines;
|
||||
std::shared_ptr<Font> mFont;
|
||||
|
||||
static std::shared_ptr<Text> New(const std::string& id, const std::string& text);
|
||||
Text(const std::string& id, const std::string& text);
|
||||
~Text() = default;
|
||||
|
||||
void SetText(const std::string& text);
|
||||
|
||||
void Calculate() override;
|
||||
void UpdateInput(InputManager* manager) override {};
|
||||
void Draw(int z) override;
|
||||
|
||||
float CalculateWidth();
|
||||
private:
|
||||
};
|
||||
}
|
||||
90
Nuake/src/UI/Nodes/TextInput.h
Normal file
90
Nuake/src/UI/Nodes/TextInput.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
#include <NuakeUI/Nodes/Node.h>
|
||||
#include <NuakeUI/Nodes/Text.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class TextInput : public Node
|
||||
{
|
||||
private:
|
||||
std::string Buffer = "";
|
||||
TextPtr TextLabel;
|
||||
uint32_t _cursorIdx = 0;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<TextInput> New(const std::string& id, const std::string& name)
|
||||
{
|
||||
return std::make_shared<TextInput>(id, name);
|
||||
}
|
||||
|
||||
TextInput(const std::string& id, const std::string& name)
|
||||
{
|
||||
InitializeNode();
|
||||
CanGrabFocus = true;
|
||||
|
||||
std::map<StyleProperties, PropValue> styles;
|
||||
styles[StyleProperties::BackgroundColor] = Color(1.f, 0.f, 0.f, 255.f);
|
||||
styles[StyleProperties::BorderColor] = Color(0.f, 255.f, 0.f, 255.f);
|
||||
styles[StyleProperties::Height] = PropValue(PropValueType::Auto, 20.f);
|
||||
styles[StyleProperties::BorderSize] = 2.0f;
|
||||
|
||||
ComputedStyle.BorderRadius = 4.0f;
|
||||
ComputedStyle.BorderSize = 2.0f;
|
||||
ComputedStyle.MaxWidth = { 200.f, LengthType::Pixel };
|
||||
ComputedStyle.Overflow = OverflowType::Hidden;
|
||||
styles[StyleProperties::PaddingLeft] = PropValue(PropValueType::Pixel, 8.f);
|
||||
styles[StyleProperties::PaddingTop] = PropValue(PropValueType::Pixel, 4.f);
|
||||
styles[StyleProperties::PaddingBottom] = PropValue(PropValueType::Pixel, 4.f);
|
||||
styles[StyleProperties::PaddingRight] = PropValue(PropValueType::Pixel, 8.f);
|
||||
ApplyStyleProperties(styles);
|
||||
|
||||
TextLabel = Text::New("textInput", "");
|
||||
|
||||
InsertChild(TextLabel);
|
||||
}
|
||||
|
||||
~TextInput() = default;
|
||||
|
||||
virtual void OnTick(InputManager* inputManager) override
|
||||
{
|
||||
TextLabel->SetText(Buffer);
|
||||
|
||||
if (HasFocus())
|
||||
{
|
||||
if (std::size(inputManager->InputStack) > 0)
|
||||
{
|
||||
std::string result = inputManager->ConsumeStack();
|
||||
if (result == "_backspace")
|
||||
{
|
||||
if (std::size(Buffer) > 0)
|
||||
Buffer.erase(Buffer.end() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer += result;
|
||||
}
|
||||
}
|
||||
|
||||
ComputedStyle.BorderSize = 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputedStyle.BorderSize = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(InputManager* inputManager) override
|
||||
{
|
||||
if (!HasFocus())
|
||||
{
|
||||
while (inputManager->InputStack.size() > 0)
|
||||
{
|
||||
inputManager->ConsumeStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
4
Nuake/src/UI/NuakeUI.cpp
Normal file
4
Nuake/src/UI/NuakeUI.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace NuakeUI
|
||||
{
|
||||
|
||||
}
|
||||
51
Nuake/src/UI/NuakeUI.h
Normal file
51
Nuake/src/UI/NuakeUI.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
/*
|
||||
Welcome to NuakeUI,
|
||||
first of all thank you for using this library.
|
||||
|
||||
How to use:
|
||||
1. Include this header file
|
||||
2. Create a CanvasParser object and parse an xml file using the Parse method.
|
||||
It returns a pointer to your canvas object.
|
||||
3. Create an InputManager class that inherits from the InputManager.h interface.
|
||||
4. Register the input manager on your canvas object returned by the Parse method of earlier with the SetInputManager method
|
||||
5. Call the 3 follow methods in your main loop:
|
||||
1. canvas->ComputeLayout(myWindowSize);
|
||||
2. canvas->Tick();
|
||||
3. canvas->Draw();
|
||||
6. You are now rendering your UI.
|
||||
|
||||
Contribute:
|
||||
If you wish to know more about the other features like DataModel binding, styling options,
|
||||
Fragments, and responsive layouts, you should look at the ReadMe of the repository or look at the
|
||||
demo projects which goes more in depth.
|
||||
|
||||
Original repository: https://github.com/antopilo/nuakeui
|
||||
Demo repository: https://github.com/antopilo/nuakeuidemo
|
||||
|
||||
In case you have any feature requests, or encounter issues with the project.
|
||||
Please fill them on the issues page on the repository.
|
||||
|
||||
Thank you,
|
||||
antopilo
|
||||
|
||||
*/
|
||||
|
||||
#include "src/UI/Nodes/Button.h"
|
||||
#include "src/UI/Renderer.h"
|
||||
|
||||
#include "Parsers/CanvasParser.h"
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- FIX z-index mouse hover
|
||||
- FIX mouse events when window not focused
|
||||
- CSS Variables
|
||||
- Color
|
||||
- Units
|
||||
- Make them global?
|
||||
- CSS background image
|
||||
- <div> Active state
|
||||
- <svg> Tag? with nano svg
|
||||
- Text overflow clipping not working
|
||||
*/
|
||||
289
Nuake/src/UI/Parsers/CanvasParser.cpp
Normal file
289
Nuake/src/UI/Parsers/CanvasParser.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "CanvasParser.h"
|
||||
|
||||
#include "../Nodes/Canvas.h"
|
||||
|
||||
#include "../Nodes/Text.h"
|
||||
#include "../Nodes/Button.h"
|
||||
|
||||
#include "../FileSystem.h"
|
||||
#include "StyleSheetParser.h"
|
||||
#include "../StringHelper.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <charconv>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
CanvasParser::CanvasParser()
|
||||
{
|
||||
RegisterNodeType("div", Node::New);
|
||||
RegisterNodeType("text", Text::New);
|
||||
RegisterNodeType("button", Button::New);
|
||||
}
|
||||
|
||||
void CanvasParser::RegisterNodeType(const std::string& name, refNew refConstructor)
|
||||
{
|
||||
NodeTypes[name] = refConstructor;
|
||||
}
|
||||
|
||||
bool CanvasParser::HasNodeType(const std::string& name) const
|
||||
{
|
||||
return NodeTypes.find(name) != NodeTypes.end();
|
||||
}
|
||||
|
||||
refNew CanvasParser::GetNodeType(const std::string& name) const
|
||||
{
|
||||
if (HasNodeType(name))
|
||||
{
|
||||
return NodeTypes.at(name);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodePtr CanvasParser::CreateNodeFromXML(tinyxml2::XMLElement* xml, const std::string& id)
|
||||
{
|
||||
NodePtr newNode;
|
||||
std::string nodeId = id;
|
||||
std::string type = xml->Value();
|
||||
std::string text = xml->GetText() ? xml->GetText() : "";
|
||||
|
||||
if (HasNodeType(type))
|
||||
{
|
||||
newNode = GetNodeType(type)(nodeId, text);
|
||||
newNode->Type = type;
|
||||
|
||||
if (!newNode->HasBeenInitialized())
|
||||
{
|
||||
newNode->InitializeNode();
|
||||
}
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
void CanvasParser::AddClassesToNode(tinyxml2::XMLElement* e, NodePtr node)
|
||||
{
|
||||
auto classAttribute = e->FindAttribute("class");
|
||||
if (!classAttribute)
|
||||
return;
|
||||
|
||||
std::string strClasses = classAttribute->Value();
|
||||
node->Classes = StringHelper::Split(strClasses, ' ');
|
||||
}
|
||||
|
||||
void CanvasParser::WriteValueFromString(std::variant<int, float, bool, std::string, char>& var, const std::string& str)
|
||||
{
|
||||
// Determine type of value
|
||||
if (str.find("'") != std::string::npos)
|
||||
{
|
||||
// Removing second bracket
|
||||
const auto& stringSplit = StringHelper::Split(str, "'");
|
||||
var = stringSplit[1];
|
||||
}
|
||||
else if (str.find(".") != std::string::npos)
|
||||
{
|
||||
const auto& begin = str.data();
|
||||
const auto& end = begin + std::size(str);
|
||||
float rightFloat;
|
||||
std::from_chars(begin, end, rightFloat);
|
||||
var = rightFloat;
|
||||
}
|
||||
else if (str.find("true") != std::string::npos)
|
||||
{
|
||||
var = true;
|
||||
}
|
||||
else if (str.find("false") != std::string::npos)
|
||||
{
|
||||
var = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& begin = str.data();
|
||||
const auto& end = begin + std::size(str);
|
||||
int rightInt;
|
||||
std::from_chars(begin, end, rightInt);
|
||||
var = rightInt;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasParser::AddModelIfToNode(tinyxml2::XMLElement* e, NodePtr node)
|
||||
{
|
||||
if (auto modelIf = e->FindAttribute("if"); modelIf)
|
||||
{
|
||||
std::string ifCondition = modelIf->Value();
|
||||
ifCondition = StringHelper::RemoveChar(ifCondition, ' ');
|
||||
|
||||
ComparaisonType compType = ComparaisonType::None;
|
||||
std::vector<std::string> splits;
|
||||
|
||||
const std::vector<std::string> operators { "==", "!=", ">=", "<=", ">", "<" };
|
||||
for (auto i = 0; i < std::size(operators); i++)
|
||||
{
|
||||
std::string operatorString = operators[i];
|
||||
if (ifCondition.find(operatorString) != std::string::npos)
|
||||
{
|
||||
compType = (ComparaisonType)i;
|
||||
splits = StringHelper::Split(ifCondition, operatorString);
|
||||
}
|
||||
}
|
||||
|
||||
if (std::size(splits) < 2 || compType == ComparaisonType::None)
|
||||
return;
|
||||
|
||||
auto operation = DataModelOperation::New(splits[0], OperationType::If, compType);
|
||||
WriteValueFromString(operation->Right, splits[1]);
|
||||
|
||||
node->AddDataModelOperation(operation);
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasParser::AddModelClasses(tinyxml2::XMLElement* e, NodePtr node)
|
||||
{
|
||||
auto currentAttribute = e->FirstAttribute();
|
||||
|
||||
while (currentAttribute)
|
||||
{
|
||||
std::string attributeName = currentAttribute->Name();
|
||||
if (attributeName == "modelClass")
|
||||
{
|
||||
std::string attributeValue = currentAttribute->Value();
|
||||
auto attributeValueSplits = StringHelper::Split(attributeValue, ':');
|
||||
|
||||
if (std::size(attributeValueSplits) < 2)
|
||||
continue;
|
||||
|
||||
std::string className = StringHelper::RemoveChar(attributeValueSplits[0], '[');
|
||||
className = StringHelper::RemoveChar(className, ']');
|
||||
|
||||
ComparaisonType compType = ComparaisonType::None;
|
||||
std::vector<std::string> splits;
|
||||
|
||||
// TODO: Move to another reusable method.
|
||||
const std::vector<std::string> operators{ "==", "!=", ">=", "<=", ">", "<" };
|
||||
for (auto i = 0; i < std::size(operators); i++)
|
||||
{
|
||||
std::string operatorString = operators[i];
|
||||
std::string logicalExpression = attributeValueSplits[1];
|
||||
if (logicalExpression.find(operatorString) != std::string::npos)
|
||||
{
|
||||
compType = (ComparaisonType)i;
|
||||
splits = StringHelper::Split(logicalExpression, operatorString);
|
||||
}
|
||||
}
|
||||
|
||||
if (std::size(splits) < 2 || compType == ComparaisonType::None)
|
||||
return;
|
||||
|
||||
std::string dataProp = StringHelper::RemoveChar(splits[0], ' ');
|
||||
auto operation = DataModelOperation::New(dataProp, OperationType::IfClass, compType);
|
||||
WriteValueFromString(operation->Right, StringHelper::RemoveChar(splits[1], ' '));
|
||||
operation->ClassName = className;
|
||||
node->AddDataModelOperation(operation);
|
||||
}
|
||||
currentAttribute = currentAttribute->Next();
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasParser::ScanFragment(tinyxml2::XMLElement* e, NodePtr node)
|
||||
{
|
||||
// We have a <fragment> with a src path.
|
||||
const std::string nodeType = e->Value();
|
||||
if (nodeType == "fragment")
|
||||
{
|
||||
if (auto srcAttr = e->FindAttribute("src"); srcAttr)
|
||||
{
|
||||
std::string fragmentPath = _parsingPath + "/../" + srcAttr->Value();
|
||||
if (FileSystem::FileExists(fragmentPath))
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (tinyxml2::XMLError error = doc.LoadFile(fragmentPath.c_str()))
|
||||
{
|
||||
doc.PrintError();
|
||||
}
|
||||
|
||||
auto firstNode = doc.FirstChildElement();
|
||||
IterateOverElement(firstNode, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Fragment src attributes error. Cant find file at: " << fragmentPath << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasParser::IterateOverElement(tinyxml2::XMLElement* e, NodePtr node)
|
||||
{
|
||||
tinyxml2::XMLElement* current = e;
|
||||
while (current)
|
||||
{
|
||||
std::string id = "Node";
|
||||
|
||||
// Look if the node has an id.
|
||||
auto idAttribute = current->FindAttribute("id");
|
||||
if (idAttribute)
|
||||
{
|
||||
id = idAttribute->Value();
|
||||
}
|
||||
|
||||
ScanFragment(current, node);
|
||||
|
||||
|
||||
NodePtr newNode = CreateNodeFromXML(current, id);
|
||||
if (newNode)
|
||||
{
|
||||
AddClassesToNode(current, newNode);
|
||||
AddModelIfToNode(current, newNode);
|
||||
AddModelClasses(current, newNode);
|
||||
|
||||
// Insert in the tree
|
||||
node->InsertChild(newNode);
|
||||
|
||||
// Recursivity on the childs of the current node.
|
||||
IterateOverElement(current->FirstChildElement(), newNode);
|
||||
}
|
||||
|
||||
// Continue to the sibbling after going Depth first.
|
||||
current = current->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
CanvasPtr CanvasParser::Parse(const std::string& path)
|
||||
{
|
||||
_parsingPath = path;
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (tinyxml2::XMLError error = doc.LoadFile(path.c_str()))
|
||||
{
|
||||
doc.PrintError();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CanvasPtr canvas = Canvas::New();
|
||||
NodePtr root = Node::New("root");
|
||||
|
||||
auto firstNode = doc.FirstChildElement();
|
||||
if (!firstNode)
|
||||
{
|
||||
return canvas;
|
||||
}
|
||||
|
||||
// Look for stylesheet attribute in root.
|
||||
auto styleSheet = firstNode->FindAttribute("stylesheet");
|
||||
if (styleSheet)
|
||||
{
|
||||
std::string relativePath = path + "/../" + styleSheet->Value();
|
||||
if (FileSystem::FileExists(relativePath))
|
||||
{
|
||||
auto styleSheet = StyleSheetParser::Get().Parse(relativePath);
|
||||
canvas->SetStyleSheet(styleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
IterateOverElement(firstNode, root);
|
||||
|
||||
canvas->SetRoot(root);
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
44
Nuake/src/UI/Parsers/CanvasParser.h
Normal file
44
Nuake/src/UI/Parsers/CanvasParser.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "../Nodes/Canvas.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <msdfgen/include/tinyxml2.h>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
typedef std::function<NodePtr(std::string, std::string)> refNew;
|
||||
|
||||
class CanvasParser
|
||||
{
|
||||
private:
|
||||
std::map<std::string, refNew> NodeTypes;
|
||||
std::string _parsingPath;
|
||||
|
||||
public:
|
||||
CanvasParser();
|
||||
~CanvasParser() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Register a custom node type.
|
||||
/// </summary>
|
||||
/// <param name="name">XML tag</param>
|
||||
/// <param name="refConstructor">pointer to method that returns a shared pointer.</param>
|
||||
void RegisterNodeType(const std::string& name, refNew refConstructor);
|
||||
bool HasNodeType(const std::string& name) const;
|
||||
refNew GetNodeType(const std::string& name) const;
|
||||
|
||||
CanvasPtr Parse(const std::string& file);
|
||||
private:
|
||||
void ScanFragment(tinyxml2::XMLElement* e, NodePtr node);
|
||||
void WriteValueFromString(std::variant<int, float, bool, std::string, char>& var, const std::string& str);
|
||||
void IterateOverElement(tinyxml2::XMLElement* e, NodePtr node);
|
||||
NodePtr CreateNodeFromXML(tinyxml2::XMLElement* xml, const std::string& id = "Node");
|
||||
void AddClassesToNode(tinyxml2::XMLElement* e, NodePtr node);
|
||||
void AddModelIfToNode(tinyxml2::XMLElement* e, NodePtr node);
|
||||
void AddModelClasses(tinyxml2::XMLElement* e, NodePtr node);
|
||||
};
|
||||
}
|
||||
374
Nuake/src/UI/Parsers/StyleSheetParser.cpp
Normal file
374
Nuake/src/UI/Parsers/StyleSheetParser.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
#include "StyleSheetParser.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include "../FileSystem.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
std::shared_ptr<StyleSheet> StyleSheetParser::Parse(const std::string& path)
|
||||
{
|
||||
assert(FileSystem::FileExists(path));
|
||||
|
||||
_parsingPath = path;
|
||||
|
||||
std::string fileContent = FileSystem::ReadFile(path);
|
||||
auto data = katana_parse(fileContent.c_str(), fileContent.length(), KatanaParserModeStylesheet);
|
||||
|
||||
auto styleSheet = StyleSheet::New();
|
||||
// Print out errors.
|
||||
if (data->errors.length > 0)
|
||||
{
|
||||
KatanaArray errors = data->errors;
|
||||
for (uint32_t i = 0; i < errors.length; i++)
|
||||
{
|
||||
KatanaError* error = (KatanaError*)errors.data[i];
|
||||
std::cout << "Failed to parse css file \"" + path + "\"." << std::endl;
|
||||
std::cout << "Error is " << error->message << std::endl;
|
||||
std::cout << "ERROR at line " + std::to_string(error->first_line) +
|
||||
" : " + std::to_string(error->first_column) << std::endl;
|
||||
}
|
||||
return styleSheet;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseRules(data->stylesheet, styleSheet);
|
||||
}
|
||||
|
||||
_visitedFiles.clear();
|
||||
|
||||
return styleSheet;
|
||||
}
|
||||
|
||||
bool StyleSheetParser::FileAlreadyVisited(const std::string& path)
|
||||
{
|
||||
return std::find(_visitedFiles.begin(), _visitedFiles.end(), path) != _visitedFiles.end();
|
||||
}
|
||||
|
||||
void StyleSheetParser::ParseRules(KatanaStylesheet* katanaStylesheet, StyleSheetPtr stylesheet)
|
||||
{
|
||||
// Import files first
|
||||
auto imports = katanaStylesheet->imports;
|
||||
for (uint32_t i = 0; i < imports.length; i++)
|
||||
{
|
||||
KatanaImportRule* importRule = static_cast<KatanaImportRule*>(imports.data[i]);
|
||||
ParseImportRule(importRule, stylesheet);
|
||||
}
|
||||
|
||||
// Parse generic rules
|
||||
auto rules = katanaStylesheet->rules;
|
||||
for (uint32_t i = 0; i < rules.length; i++)
|
||||
{
|
||||
KatanaRule* rule = (KatanaRule*)rules.data[i];
|
||||
|
||||
auto ruleType = rule->type;
|
||||
switch (ruleType)
|
||||
{
|
||||
case KatanaRuleStyle: // Not sure if needed.
|
||||
ParseStyleRule(rule, stylesheet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StyleSheetParser::ParseImportRule(KatanaImportRule* rule, StyleSheetPtr styleSheet)
|
||||
{
|
||||
std::string path = rule->href;
|
||||
|
||||
if (FileAlreadyVisited(path))
|
||||
{
|
||||
std::cout << "Cyclic file import detected! " << "File is: " << path << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_visitedFiles.push_back(path);
|
||||
|
||||
if (!FileSystem::FileExists(path))
|
||||
{
|
||||
std::cout << "CSS Import rule error: Cannot find file: " << path << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fileContent = FileSystem::ReadFile(path);
|
||||
auto data = katana_parse(fileContent.c_str(), fileContent.length(), KatanaParserModeStylesheet);
|
||||
|
||||
if (data->errors.length > 0)
|
||||
{
|
||||
KatanaArray errors = data->errors;
|
||||
for (uint32_t i = 0; i < errors.length; i++)
|
||||
{
|
||||
KatanaError* error = (KatanaError*)errors.data[i];
|
||||
std::cout << "Failed to parse css file \"" + path + "\"." << std::endl;
|
||||
std::cout << "Error is " << error->message << std::endl;
|
||||
std::cout << "ERROR at line " + std::to_string(error->first_line) +
|
||||
" : " + std::to_string(error->first_column) << std::endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ParseRules(data->stylesheet, styleSheet);
|
||||
}
|
||||
|
||||
StyleProperties GetPropFromString(const std::string& prop)
|
||||
{
|
||||
if (prop == "height") return StyleProperties::Height;
|
||||
else if (prop == "max-height") return StyleProperties::MaxHeight;
|
||||
else if (prop == "min-height") return StyleProperties::MinHeight;
|
||||
else if (prop == "width") return StyleProperties::Width;
|
||||
else if (prop == "max-width") return StyleProperties::MaxWidth;
|
||||
else if (prop == "min-width") return StyleProperties::MinWidth;
|
||||
else if (prop == "padding-left") return StyleProperties::PaddingLeft;
|
||||
else if (prop == "padding-right") return StyleProperties::PaddingRight;
|
||||
else if (prop == "padding-top") return StyleProperties::PaddingTop;
|
||||
else if (prop == "padding-bottom") return StyleProperties::PaddingBottom;
|
||||
else if (prop == "margin-left") return StyleProperties::MarginLeft;
|
||||
else if (prop == "margin-right") return StyleProperties::MarginRight;
|
||||
else if (prop == "margin-top") return StyleProperties::MarginTop;
|
||||
else if (prop == "margin-bottom") return StyleProperties::MarginBottom;
|
||||
else if (prop == "position") return StyleProperties::Position;
|
||||
else if (prop == "align-items") return StyleProperties::AlignItems;
|
||||
else if (prop == "self-align") return StyleProperties::SelfAlign;
|
||||
else if (prop == "aspect-ratio") return StyleProperties::AspectRatio;
|
||||
else if (prop == "flex-direction") return StyleProperties::FlexDirection;
|
||||
else if (prop == "flex-wrap") return StyleProperties::FlexWrap;
|
||||
else if (prop == "flex-basis") return StyleProperties::FlexBasis;
|
||||
else if (prop == "flex-grow") return StyleProperties::FlexGrow;
|
||||
else if (prop == "flex-shrink") return StyleProperties::FlexShrink;
|
||||
else if (prop == "justify-content") return StyleProperties::JustifyContent;
|
||||
else if (prop == "align-content") return StyleProperties::AlignContent;
|
||||
else if (prop == "layout-direction") return StyleProperties::LayoutDirection;
|
||||
else if (prop == "border-size") return StyleProperties::BorderSize;
|
||||
else if (prop == "border-radius") return StyleProperties::BorderRadius;
|
||||
else if (prop == "border-color") return StyleProperties::BorderColor;
|
||||
else if (prop == "background-color") return StyleProperties::BackgroundColor;
|
||||
else if (prop == "text-align") return StyleProperties::TextAlign;
|
||||
else if (prop == "color") return StyleProperties::Color;
|
||||
else if (prop == "overflow") return StyleProperties::Overflow;
|
||||
else if (prop == "font-size") return StyleProperties::FontSize;
|
||||
else if (prop == "visibility") return StyleProperties::Visibility;
|
||||
else if (prop == "z-index") return StyleProperties::ZIndex;
|
||||
else if (prop == "top") return StyleProperties::Top;
|
||||
else if (prop == "bottom") return StyleProperties::Bottom;
|
||||
else if (prop == "left") return StyleProperties::Left;
|
||||
else if (prop == "right") return StyleProperties::Right;
|
||||
else if (prop == "background-image") return StyleProperties::BackgroundImage;
|
||||
return StyleProperties::None;
|
||||
}
|
||||
|
||||
void StyleSheetParser::ParseStyleRule(KatanaRule* rule, StyleSheetPtr styleSheet)
|
||||
{
|
||||
auto styleRule = reinterpret_cast<KatanaStyleRule*>(rule);
|
||||
std::string styleName = rule->name;
|
||||
|
||||
for (uint32_t s = 0; s < styleRule->selectors->length; s++)
|
||||
{
|
||||
auto styleSelector = std::vector<StyleSelector>();
|
||||
|
||||
// unsafe c-style void* in the array.
|
||||
void* selectorData = styleRule->selectors->data[s];
|
||||
auto selector = reinterpret_cast<KatanaSelector*>(selectorData);
|
||||
while (selector)
|
||||
{
|
||||
auto match = selector->match; // tag, id or class
|
||||
switch (match)
|
||||
{
|
||||
case KatanaSelectorMatchPseudoClass:
|
||||
{
|
||||
std::string matchPseudo = selector->data->value;
|
||||
styleSelector.push_back({ StyleSelectorType::Pseudo, matchPseudo });
|
||||
}
|
||||
break;
|
||||
case KatanaSelectorMatchTag:
|
||||
{
|
||||
std::string matchTag = selector->tag->local;
|
||||
styleSelector.push_back({ StyleSelectorType::Tag, matchTag });
|
||||
}
|
||||
break;
|
||||
case KatanaSelectorMatchId:
|
||||
{
|
||||
std::string matchId = selector->data->value;
|
||||
styleSelector.push_back({ StyleSelectorType::Id, matchId });
|
||||
}
|
||||
break;
|
||||
case KatanaSelectorMatchClass:
|
||||
{
|
||||
std::string matchClass = selector->data->value;
|
||||
styleSelector.push_back({ StyleSelectorType::Class, matchClass });
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
selector = selector->tagHistory;
|
||||
}
|
||||
|
||||
// Added the new rule with selectors.
|
||||
auto newRule = StyleRule(styleSelector);
|
||||
|
||||
// Now add the properties to the new rule.
|
||||
for (uint32_t d = 0; d < styleRule->declarations->length; d++)
|
||||
{
|
||||
// unsafe c-style void* in the array.
|
||||
void* declarationData = styleRule->declarations->data[d];
|
||||
auto declaration = reinterpret_cast<KatanaDeclaration*>(declarationData);
|
||||
|
||||
// convert from string to property enum.
|
||||
StyleProperties propType = GetPropFromString(declaration->property);
|
||||
|
||||
PropValue propValue{};
|
||||
for (uint32_t v = 0; v < declaration->values->length; v++)
|
||||
{
|
||||
// unsafe c-style voir* in the array.
|
||||
void* valueData = declaration->values->data[v];
|
||||
KatanaValue* value = reinterpret_cast<KatanaValue*>(valueData);
|
||||
|
||||
switch (value->unit)
|
||||
{
|
||||
case KatanaValueUnit::KATANA_VALUE_STRING:
|
||||
{
|
||||
std::string stringValue = value->string;
|
||||
if (propType == StyleProperties::BackgroundImage)
|
||||
{
|
||||
stringValue = _parsingPath + "/../" + stringValue;
|
||||
}
|
||||
propValue.string = stringValue;
|
||||
propValue.type = PropValueType::String;
|
||||
}
|
||||
break;
|
||||
case KatanaValueUnit::KATANA_VALUE_PERCENTAGE:
|
||||
case KatanaValueUnit::KATANA_VALUE_PX:
|
||||
{
|
||||
propValue.value.Number = (float)value->fValue;
|
||||
propValue.type = value->unit == KatanaValueUnit::KATANA_VALUE_PX ? PropValueType::Pixel : PropValueType::Percent;
|
||||
}
|
||||
break;
|
||||
case KatanaValueUnit::KATANA_VALUE_PARSER_HEXCOLOR:
|
||||
{
|
||||
int r, g, b, a = 255;
|
||||
int result = sscanf_s(value->string, "%02x%02x%02x%02x", &r, &g, &b, &a);
|
||||
propValue.value.Color = Color(r, g, b, a);
|
||||
propValue.type = PropValueType::Color;
|
||||
}
|
||||
break;
|
||||
case KatanaValueUnit::KATANA_VALUE_UNKNOWN:
|
||||
{
|
||||
std::string valueStr = value->string;
|
||||
}
|
||||
break;
|
||||
case KatanaValueUnit::KATANA_VALUE_NUMBER:
|
||||
propValue.value.Number = (int)value->fValue;
|
||||
break;
|
||||
case KatanaValueUnit::KATANA_VALUE_IDENT:
|
||||
{
|
||||
std::string valueStr = value->string;
|
||||
if (propType == StyleProperties::Position)
|
||||
{
|
||||
PositionType positionType = PositionType::Relative;
|
||||
if (valueStr == "absolute")
|
||||
propValue.value.Enum = (int)PositionType::Absolute;
|
||||
}
|
||||
if (propType == StyleProperties::AlignContent)
|
||||
{
|
||||
AlignContentType align;
|
||||
if (valueStr == "flex-start") align = AlignContentType::FlexStart;
|
||||
else if (valueStr == "center") align = AlignContentType::Center;
|
||||
else if (valueStr == "flex-end") align = AlignContentType::FlexEnd;
|
||||
else if (valueStr == "stretch") align = AlignContentType::Stretch;
|
||||
else if (valueStr == "space-between") align = AlignContentType::SpaceBetween;
|
||||
else if (valueStr == "space-around") align = AlignContentType::SpaceAround;
|
||||
else align = AlignContentType::FlexStart;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)align;
|
||||
}
|
||||
else if (propType == StyleProperties::AlignItems || propType == StyleProperties::SelfAlign)
|
||||
{
|
||||
AlignItemsType align;
|
||||
if (valueStr == "flex-start") align = AlignItemsType::FlexStart;
|
||||
else if (valueStr == "center") align = AlignItemsType::Center;
|
||||
else if (valueStr == "flex-end") align = AlignItemsType::FlexEnd;
|
||||
else if (valueStr == "stretch") align = AlignItemsType::Stretch;
|
||||
else if (valueStr == "space-between") align = AlignItemsType::SpaceBetween;
|
||||
else if (valueStr == "space-around") align = AlignItemsType::SpaceAround;
|
||||
else align = AlignItemsType::FlexStart;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)align;
|
||||
}
|
||||
else if (propType == StyleProperties::FlexDirection)
|
||||
{
|
||||
FlexDirectionType direction = FlexDirectionType::Row;
|
||||
if (valueStr == "column") direction = FlexDirectionType::Column;
|
||||
else if (valueStr == "row-reversed") direction = FlexDirectionType::RowReversed;
|
||||
else if (valueStr == "column-reversed") direction = FlexDirectionType::ColumnReversed;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)direction;
|
||||
}
|
||||
else if (propType == StyleProperties::FlexWrap)
|
||||
{
|
||||
FlexWrapType type = FlexWrapType::Wrap;
|
||||
if (valueStr == "no-wrap") type = FlexWrapType::NoWrap;
|
||||
else if (valueStr == "wrap-reversed") type = FlexWrapType::WrapReversed;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)type;
|
||||
}
|
||||
else if (propType == StyleProperties::JustifyContent)
|
||||
{
|
||||
auto justify = JustifyContentType::FlexStart;
|
||||
if (valueStr == "center") justify = JustifyContentType::Center;
|
||||
else if (valueStr == "flex-end") justify = JustifyContentType::FlexEnd;
|
||||
else if (valueStr == "space-around") justify = JustifyContentType::SpaceAround;
|
||||
else if (valueStr == "space-between") justify = JustifyContentType::SpaceBetween;
|
||||
else if (valueStr == "space-evenly") justify = JustifyContentType::SpaceEvenly;
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)justify;
|
||||
}
|
||||
else if (propType == StyleProperties::LayoutDirection)
|
||||
{
|
||||
auto direction = LayoutDirectionType::LTR;
|
||||
if (valueStr == "RTL") direction = LayoutDirectionType::RTL;
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)direction;
|
||||
}
|
||||
else if (propType == StyleProperties::TextAlign)
|
||||
{
|
||||
auto align = TextAlignType::Left;
|
||||
if (valueStr == "center") align = TextAlignType::Center;
|
||||
if (valueStr == "right") align = TextAlignType::Right;
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)align;
|
||||
}
|
||||
else if (propType == StyleProperties::Overflow)
|
||||
{
|
||||
OverflowType overflow = OverflowType::Show;
|
||||
if (valueStr == "hidden") overflow = OverflowType::Hidden;
|
||||
else if (valueStr == "show") overflow = OverflowType::Show;
|
||||
else if (valueStr == "scroll") overflow = OverflowType::Scroll;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)overflow;
|
||||
}
|
||||
else if (propType == StyleProperties::Visibility)
|
||||
{
|
||||
VisibilityType visibility = VisibilityType::Show;
|
||||
if (valueStr == "hidden") visibility = VisibilityType::Hidden;
|
||||
|
||||
propValue.type = PropValueType::Enum;
|
||||
propValue.value.Enum = (int)visibility;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newRule.SetProp(propType, propValue);
|
||||
}
|
||||
|
||||
styleSheet->Rules.push_back(newRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Nuake/src/UI/Parsers/StyleSheetParser.h
Normal file
35
Nuake/src/UI/Parsers/StyleSheetParser.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "../Styles/StyleSheet.h"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "../Vendors/katana-parser/katana.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class StyleSheetParser
|
||||
{
|
||||
public:
|
||||
static StyleSheetParser& Get()
|
||||
{
|
||||
static StyleSheetParser parser;
|
||||
return parser;
|
||||
}
|
||||
|
||||
StyleSheetParser() = default;
|
||||
~StyleSheetParser() = default;
|
||||
|
||||
std::shared_ptr<StyleSheet> Parse(const std::string& path);
|
||||
|
||||
private:
|
||||
std::string _parsingPath;
|
||||
std::vector<std::string> _visitedFiles;
|
||||
|
||||
bool FileAlreadyVisited(const std::string& path);
|
||||
|
||||
void ParseRules(KatanaStylesheet* katanaStylesheet, StyleSheetPtr stylesheet);
|
||||
void ParseImportRule(KatanaImportRule* rule, StyleSheetPtr styleSheet);
|
||||
void ParseStyleRule(KatanaRule* rule, StyleSheetPtr stylesheet);
|
||||
};
|
||||
}
|
||||
206
Nuake/src/UI/Renderer.cpp
Normal file
206
Nuake/src/UI/Renderer.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "Renderer.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Rendering/Buffers/VertexBufferLayout.h"
|
||||
|
||||
#include "Font/Font.h"
|
||||
#include "Font/FontManager.h"
|
||||
|
||||
#include "FileSystem.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
struct Vertex {
|
||||
Vector3 Position;
|
||||
Vector2 UV;
|
||||
};
|
||||
|
||||
std::shared_ptr<Font> Renderer::mDefaultFont;
|
||||
|
||||
Renderer::Renderer()
|
||||
{
|
||||
ReloadShaders();
|
||||
|
||||
mDefaultFont = FontManager::Get().GetFont("SourceSansPro-Regular.ttf");
|
||||
|
||||
const std::vector<Vertex> vertices = {
|
||||
{ { 1.f, 1.f, 0.f }, {1.f, 0.f} },
|
||||
{ { 1.f, 0.f, 0.f }, {1.f, 1.f} },
|
||||
{ { 0.f, 1.f, 0.f }, {0.f, 0.f} },
|
||||
{ { 1.f, 0.f, 0.f }, {1.f, 1.f} },
|
||||
{ { 0.f, 0.f, 0.f }, {0.f, 1.f} },
|
||||
{ { 0.f, 1.f, 0.f }, {0.f, 0.f} },
|
||||
};
|
||||
|
||||
mVertexArray = std::make_shared<VertexArray>();
|
||||
mVertexArray->Bind();
|
||||
mVertexBuffer = std::make_shared<VertexBuffer>(vertices.data(), (unsigned int)(vertices.size() * sizeof(Vertex)));
|
||||
|
||||
auto vbl = VertexBufferLayout();
|
||||
vbl.Push<float>(3); // Position
|
||||
vbl.Push<float>(2); // UV
|
||||
|
||||
mVertexArray->AddBuffer(*mVertexBuffer, vbl);
|
||||
mVertexArray->Unbind();
|
||||
}
|
||||
|
||||
void Renderer::ReloadShaders()
|
||||
{
|
||||
// Rectangle Shader
|
||||
std::string vertexSource = FileSystem::ReadFile("../resources/panel.vert.glsl");
|
||||
std::string fragSource = FileSystem::ReadFile("../resources/panel.frag.glsl");
|
||||
mShader = std::make_shared<Shader>(vertexSource, fragSource);
|
||||
|
||||
// SDF Shader
|
||||
vertexSource = FileSystem::ReadFile("../resources/text.vert.glsl");
|
||||
fragSource = FileSystem::ReadFile("../resources/text.frag.glsl");
|
||||
mSDFShader = std::make_shared<Shader>(vertexSource, fragSource);
|
||||
}
|
||||
|
||||
void Renderer::SetViewportSize(const Vector2& size)
|
||||
{
|
||||
mSize = size;
|
||||
mView = glm::ortho(0.f, size.x, size.y, 0.f, -100.f, 100.0f);
|
||||
}
|
||||
|
||||
void Renderer::BeginDraw()
|
||||
{
|
||||
int viewportW = (int)mSize.x;
|
||||
int viewportH = (int)mSize.y;
|
||||
//glViewport(0, 0, viewportW, viewportH);
|
||||
}
|
||||
|
||||
void Renderer::DrawNode(std::shared_ptr<Node> node, int z)
|
||||
{
|
||||
//glEnable(GL_DEPTH_TEST);
|
||||
|
||||
float parentScroll = 0.f;
|
||||
float parentPaddingRight = 0.f;
|
||||
if (node->Parent)
|
||||
{
|
||||
parentScroll = node->Parent->ScrollDelta;
|
||||
}
|
||||
|
||||
const YGNodeRef yogaNode = node->GetYogaNode();
|
||||
const float width = YGNodeLayoutGetWidth(yogaNode) - parentPaddingRight;
|
||||
const float height = YGNodeLayoutGetHeight(yogaNode);
|
||||
const float padding = YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft);
|
||||
const float margin = YGNodeLayoutGetMargin(yogaNode, YGEdgeLeft);
|
||||
const float marginTop = YGNodeLayoutGetMargin(yogaNode, YGEdgeTop);
|
||||
const float left = YGNodeLayoutGetLeft(yogaNode);
|
||||
const float top = YGNodeLayoutGetTop(yogaNode) - parentScroll;
|
||||
const float borderLeft = YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft);
|
||||
|
||||
float parentLeft = 0.f;
|
||||
float parentTop = 0.f;
|
||||
|
||||
auto parent = node->Parent;
|
||||
if (parent)
|
||||
{
|
||||
parentLeft = parent->ComputedPosition.x;
|
||||
parentTop = parent->ComputedPosition.y;
|
||||
}
|
||||
|
||||
node->ComputedSize = Vector2(width, height);
|
||||
node->ComputedPosition = Vector2(left + parentLeft, top + parentTop);
|
||||
|
||||
Matrix4 transform = Matrix4(1.f);
|
||||
transform = glm::translate(transform, Vector3(left + parentLeft, top + parentTop, z));
|
||||
transform = glm::scale(transform, Vector3(width, height, 1.0f));
|
||||
|
||||
bool hasBackgroundImage = false;
|
||||
if (node->ComputedStyle.BackgroundImage)
|
||||
{
|
||||
hasBackgroundImage = true;
|
||||
node->ComputedStyle.BackgroundImage->Bind(0);
|
||||
}
|
||||
|
||||
mShader->Bind();
|
||||
//mShader->SetUniforms({
|
||||
// { "u_Model", transform },
|
||||
// { "u_Size", Vector2(width, height) },
|
||||
// { "u_View", mView },
|
||||
// { "u_Color", node->ComputedStyle.BackgroundColor },
|
||||
// { "u_Border", node->ComputedStyle.BorderSize },
|
||||
// { "u_BorderRadius", node->ComputedStyle.BorderRadius },
|
||||
// { "u_BorderColor", node->ComputedStyle.BorderColor },
|
||||
// { "u_BackgroundImage", 0 },
|
||||
// { "u_HasBackgroundImage", hasBackgroundImage ? 1.f : 0.f}
|
||||
//});
|
||||
|
||||
|
||||
//bool hideOverflow = node->Parent != nullptr && node->Parent->ComputedStyle.Overflow == OverflowType::Hidden;
|
||||
//if (hideOverflow)
|
||||
//{
|
||||
// glEnable(GL_SCISSOR_TEST);
|
||||
// Vector2 parentPosition = node->Parent->ComputedPosition;
|
||||
// Vector2 parentSize = node->Parent->ComputedSize;
|
||||
// int scissorX = (int)parentPosition.x;
|
||||
// int scissorY = 1080 - (int)(parentPosition.y - parentSize.y);
|
||||
// int scissorW = (int)parentSize.x;
|
||||
// int scissorH = (int)parentSize.y;
|
||||
// glScissor(scissorX, scissorY, scissorW, scissorH);
|
||||
//}
|
||||
|
||||
// TODO: Keep overflow until we get out of here
|
||||
|
||||
//mVertexArray->Bind();
|
||||
//glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
//mVertexArray->Unbind();
|
||||
//mShader->Unbind();
|
||||
//
|
||||
//if (hideOverflow)
|
||||
// glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
}
|
||||
|
||||
void Renderer::DrawString(const std::string& string, NodeStyle& nodeStyle, std::shared_ptr<Font> font, Vector3 position)
|
||||
{
|
||||
//const float fontSize = nodeStyle.FontSize / 64.f;
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//mSDFShader->Bind();
|
||||
//font->mAtlas->Bind(5);
|
||||
//mSDFShader->SetUniforms({
|
||||
// { "u_View", mView },
|
||||
// { "u_Atlas", 5 },
|
||||
// { "u_Scale", 1.0f},
|
||||
// { "u_SDF_BorderSize", 0.0f},
|
||||
// { "u_FontColor", nodeStyle.FontColor },
|
||||
// { "u_PxRange", fontSize },
|
||||
// { "u_SDF_BorderSize", {1.0, 1.0}}
|
||||
//});
|
||||
//
|
||||
//mVertexArray->Bind();
|
||||
//
|
||||
//float advance = 0.0f;
|
||||
//for (char const& c : string)
|
||||
//{
|
||||
// Char letter = font->GetChar((int)c);
|
||||
//
|
||||
// // Move the cursor
|
||||
// Matrix4 model = Matrix4(1.f);
|
||||
// model = glm::translate(model, position);
|
||||
// model = glm::translate(model, Vector3(advance * fontSize, (-(letter.PlaneBounds.top) + (font->LineHeight)) * fontSize, 0));
|
||||
//
|
||||
// advance += (letter.Advance);
|
||||
//
|
||||
// // Scaling of the quad
|
||||
// float scaleX = (float)(letter.PlaneBounds.right - letter.PlaneBounds.left);
|
||||
// float scaleY = (float)(letter.PlaneBounds.top - letter.PlaneBounds.bottom);
|
||||
// model = glm::scale(model, Vector3(scaleX * fontSize, scaleY * fontSize, 1.f));
|
||||
//
|
||||
// // Set Uniforms
|
||||
// mSDFShader->SetUniforms({
|
||||
// { "u_Model", model },
|
||||
// { "u_TexturePos", Vector2(letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y) },
|
||||
// { "u_TextureScale", Vector2(letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y) },
|
||||
// });
|
||||
//
|
||||
//
|
||||
// glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
//}
|
||||
//
|
||||
//
|
||||
//mVertexArray->Unbind();
|
||||
}
|
||||
}
|
||||
47
Nuake/src/UI/Renderer.h
Normal file
47
Nuake/src/UI/Renderer.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <src/Rendering/Shaders/Shader.h>
|
||||
#include <src/Rendering/Buffers/VertexBuffer.h>
|
||||
#include <src/Rendering/Buffers/VertexArray.h>
|
||||
|
||||
#include "Nodes/Node.h"
|
||||
#include "Nodes/Text.h"
|
||||
#include "Font/Font.h"
|
||||
|
||||
#include <msdf-atlas-gen/msdf-atlas-gen.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
static Renderer& Get() {
|
||||
static Renderer instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void SetViewportSize(const Vector2& size);
|
||||
|
||||
void BeginDraw();
|
||||
void DrawNode(std::shared_ptr<Node> node, int z);
|
||||
void DrawString(const std::string& string, NodeStyle& nodeStyle, std::shared_ptr<Font> font = mDefaultFont, Vector3 position = Vector3());
|
||||
void DrawChar(std::shared_ptr<Font> font, int letter);
|
||||
void DrawRect();
|
||||
|
||||
void ReloadShaders();
|
||||
static std::shared_ptr<Font> mDefaultFont;
|
||||
private:
|
||||
Vector2 mSize;
|
||||
Matrix4 mView;
|
||||
|
||||
Renderer();
|
||||
~Renderer() = default;
|
||||
|
||||
std::shared_ptr<Shader> mShader;
|
||||
std::shared_ptr<Shader> mSDFShader;
|
||||
std::shared_ptr<VertexArray> mVertexArray;
|
||||
std::shared_ptr<VertexBuffer> mVertexBuffer;
|
||||
};
|
||||
}
|
||||
56
Nuake/src/UI/StringHelper.cpp
Normal file
56
Nuake/src/UI/StringHelper.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "StringHelper.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace NuakeUI::StringHelper
|
||||
{
|
||||
std::vector<std::string> Split(std::string string, const char delimiter)
|
||||
{
|
||||
auto splittedString = std::vector<std::string>();
|
||||
|
||||
std::stringstream ss(string);
|
||||
std::string element;
|
||||
|
||||
while (getline(ss, element, delimiter))
|
||||
{
|
||||
splittedString.push_back(element);
|
||||
}
|
||||
|
||||
return splittedString;
|
||||
}
|
||||
|
||||
std::string RemoveChar(std::string string, char character)
|
||||
{
|
||||
// remove space from string
|
||||
string.erase(std::remove(string.begin(), string.end(), character), string.end());
|
||||
return string;
|
||||
}
|
||||
|
||||
std::vector<std::string> Split(std::string s, const std::string& delimiter)
|
||||
{
|
||||
auto splittedString = std::vector<std::string>();
|
||||
|
||||
std::vector<std::string> splits;
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
while ((pos = s.find(delimiter)) != std::string::npos) {
|
||||
token = s.substr(0, pos);
|
||||
splits.push_back(token);
|
||||
s.erase(0, pos + delimiter.length());
|
||||
}
|
||||
splits.push_back(s);
|
||||
|
||||
return splits;
|
||||
}
|
||||
|
||||
bool StartsWith(const std::string& str, const std::string& start)
|
||||
{
|
||||
return str.size() >= start.size() && 0 == str.compare(0, start.size(), start);
|
||||
}
|
||||
|
||||
bool EndsWith(const std::string& str, const std::string& end)
|
||||
{
|
||||
return str.size() >= end.size() && 0 == str.compare(str.size() - end.size(), end.size(), end);
|
||||
}
|
||||
}
|
||||
25
Nuake/src/UI/StringHelper.h
Normal file
25
Nuake/src/UI/StringHelper.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
namespace StringHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Splits a string into a vector of substrings.
|
||||
/// </summary>
|
||||
/// <param name="string">The string to be split</param>
|
||||
/// <param name="delimiter">The token</param>
|
||||
/// <returns></returns>
|
||||
std::vector<std::string> Split(std::string string, const char delimiter);
|
||||
|
||||
std::string RemoveChar(std::string string, char character);
|
||||
|
||||
std::vector<std::string> Split(std::string s, const std::string& delimiter);
|
||||
|
||||
bool StartsWith(const std::string& str, const std::string& start);
|
||||
|
||||
bool EndsWith(const std::string& str, const std::string& end);
|
||||
}
|
||||
}
|
||||
6
Nuake/src/UI/Styles/Style.h
Normal file
6
Nuake/src/UI/Styles/Style.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
|
||||
}
|
||||
6
Nuake/src/UI/Styles/StyleSheet.cpp
Normal file
6
Nuake/src/UI/Styles/StyleSheet.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "StyleSheet.h"
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
|
||||
}
|
||||
139
Nuake/src/UI/Styles/StyleSheet.h
Normal file
139
Nuake/src/UI/Styles/StyleSheet.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
#include "../Nodes/NodeState.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <src/Core/Maths.h>
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
namespace NuakeUI
|
||||
{
|
||||
enum class StyleProperties {
|
||||
None, Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight,
|
||||
Top, Bottom, Left, Right,
|
||||
PaddingLeft, PaddingTop, PaddingRight, PaddingBottom,
|
||||
MarginLeft, MarginTop, MarginRight, MarginBottom,
|
||||
Position, AlignItems, SelfAlign,
|
||||
AspectRatio, FlexDirection, FlexWrap, FlexBasis, FlexGrow, FlexShrink,
|
||||
JustifyContent, AlignContent, LayoutDirection,
|
||||
BorderSize, BorderRadius, BorderColor,
|
||||
BackgroundColor, TextAlign, Color, Overflow, FontSize, Visibility, ZIndex,
|
||||
BackgroundImage
|
||||
};
|
||||
enum class PositionType { Relative, Absolute };
|
||||
enum class AlignItemsType { Auto, FlexStart, Center, FlexEnd, Stretch, Baseline, SpaceBetween, SpaceAround };
|
||||
enum class FlexWrapType { NoWrap, Wrap, WrapReversed };
|
||||
enum class JustifyContentType { FlexStart, FlexEnd, Center, SpaceBetween, SpaceAround, SpaceEvenly };
|
||||
enum class FlexDirectionType { Row = 0, Column, RowReversed, ColumnReversed };
|
||||
enum class AlignContentType { FlexStart, FlexEnd, Stretch, Center, SpaceBetween, SpaceAround };
|
||||
enum class LayoutDirectionType { LTR = 2, RTL = 3 };
|
||||
|
||||
enum class TextAlignType
|
||||
{
|
||||
Left, Center, Right
|
||||
};
|
||||
|
||||
enum class OverflowType { Show, Hidden, Scroll };
|
||||
enum class VisibilityType {Show, Hidden};
|
||||
|
||||
// Style Values
|
||||
enum class PropValueType { Pixel , Percent, Auto, Color, Enum, String };
|
||||
|
||||
union Value
|
||||
{
|
||||
float Number;
|
||||
Color Color;
|
||||
int Enum;
|
||||
};
|
||||
|
||||
struct PropValue
|
||||
{
|
||||
PropValueType type;
|
||||
Value value;
|
||||
std::string string;
|
||||
|
||||
PropValue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PropValue(PropValueType t, float f)
|
||||
{
|
||||
type = t;
|
||||
value.Number = f;
|
||||
}
|
||||
|
||||
PropValue(int i)
|
||||
{
|
||||
type = PropValueType::Enum;
|
||||
value.Enum = i;
|
||||
}
|
||||
|
||||
PropValue(Color c)
|
||||
{
|
||||
type = PropValueType::Color;
|
||||
value.Color = c;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Selector
|
||||
enum class StyleSelectorType { Id, Class, Tag, Pseudo };
|
||||
|
||||
struct StyleSelector
|
||||
{
|
||||
StyleSelectorType Type;
|
||||
std::string Value;
|
||||
};
|
||||
|
||||
class StyleRule
|
||||
{
|
||||
public:
|
||||
std::vector<StyleSelector> Selector;
|
||||
|
||||
std::map<StyleProperties, PropValue> Properties;
|
||||
|
||||
StyleRule(std::vector<StyleSelector> selector) : Selector(selector)
|
||||
{
|
||||
Properties = std::map<StyleProperties, PropValue>();
|
||||
}
|
||||
|
||||
void SetProp(StyleProperties prop, PropValue value)
|
||||
{
|
||||
Properties[prop] = value;
|
||||
}
|
||||
|
||||
PropValue GetProp(StyleProperties prop)
|
||||
{
|
||||
if (HasProp(prop))
|
||||
return Properties[prop];
|
||||
|
||||
return PropValue();
|
||||
}
|
||||
|
||||
bool HasProp(StyleProperties prop)
|
||||
{
|
||||
return Properties.find(prop) != Properties.end();
|
||||
}
|
||||
};
|
||||
|
||||
class StyleSheet;
|
||||
typedef std::shared_ptr<StyleSheet> StyleSheetPtr;
|
||||
class StyleSheet
|
||||
{
|
||||
public:
|
||||
std::vector<StyleRule> Rules;
|
||||
|
||||
static StyleSheetPtr New()
|
||||
{
|
||||
return std::make_shared<StyleSheet>();
|
||||
}
|
||||
|
||||
StyleSheet() = default;
|
||||
~StyleSheet() = default;
|
||||
};
|
||||
}
|
||||
3
Nuake/src/UI/UIInputManager.cpp
Normal file
3
Nuake/src/UI/UIInputManager.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "UIInputManager.h"
|
||||
|
||||
using namespace Nuake;
|
||||
89
Nuake/src/UI/UIInputManager.h
Normal file
89
Nuake/src/UI/UIInputManager.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "InputManager.h"
|
||||
|
||||
#include <src/Window.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class MyInputManager : public NuakeUI::InputManager
|
||||
{
|
||||
public:
|
||||
MyInputManager(Window& window)
|
||||
{
|
||||
mWindow = window.GetHandle();
|
||||
|
||||
glfwSetScrollCallback(mWindow, MyInputManager::scroll_callback);
|
||||
glfwSetCharCallback(mWindow, MyInputManager::char_callback);
|
||||
glfwSetKeyCallback(mWindow, MyInputManager::key_callback);
|
||||
}
|
||||
|
||||
bool IsMouseInputDown() override
|
||||
{
|
||||
auto state = glfwGetMouseButton(mWindow, GLFW_MOUSE_BUTTON_1);
|
||||
return state == GLFW_PRESS;
|
||||
}
|
||||
|
||||
bool IsKeyPressed(uint32_t key) override
|
||||
{
|
||||
auto states = glfwGetKey(mWindow, key);
|
||||
return states == GLFW_PRESS;
|
||||
}
|
||||
|
||||
float GetMouseX() override
|
||||
{
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(mWindow, &xpos, &ypos);
|
||||
return (float)xpos;
|
||||
}
|
||||
|
||||
float GetMouseY() override
|
||||
{
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(mWindow, &xpos, &ypos);
|
||||
return (float)ypos;
|
||||
}
|
||||
|
||||
float GetScrollX() override
|
||||
{
|
||||
return ScrollX;
|
||||
}
|
||||
|
||||
float GetScrollY() override
|
||||
{
|
||||
return ScrollY;
|
||||
}
|
||||
|
||||
static void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
ScrollX = (float)xoffset;
|
||||
ScrollY = (float)yoffset;
|
||||
}
|
||||
|
||||
static void char_callback(GLFWwindow* window, unsigned int codepoint)
|
||||
{
|
||||
char c[5] = { 0x00,0x00,0x00,0x00,0x00 };
|
||||
if (codepoint <= 0x7F) { c[0] = codepoint; }
|
||||
else if (codepoint <= 0x7FF) { c[0] = (codepoint >> 6) + 192; c[1] = (codepoint & 63) + 128; }
|
||||
else if (0xd800 <= codepoint && codepoint <= 0xdfff) {} //invalid block of utf8
|
||||
else if (codepoint <= 0xFFFF) { c[0] = (codepoint >> 12) + 224; c[1] = ((codepoint >> 6) & 63) + 128; c[2] = (codepoint & 63) + 128; }
|
||||
else if (codepoint <= 0x10FFFF) { c[0] = (codepoint >> 18) + 240; c[1] = ((codepoint >> 12) & 63) + 128; c[2] = ((codepoint >> 6) & 63) + 128; c[3] = (codepoint & 63) + 128; }
|
||||
|
||||
InputStack.push(c);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_BACKSPACE && (action == GLFW_REPEAT || action == GLFW_PRESS))
|
||||
{
|
||||
InputStack.push("_backspace");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GLFWwindow* mWindow;
|
||||
};
|
||||
}
|
||||
236
Nuake/src/Vendors/katana-parser/foundation.c
Normal file
236
Nuake/src/Vendors/katana-parser/foundation.c
Normal file
@@ -0,0 +1,236 @@
|
||||
//
|
||||
// foundation.c
|
||||
// Katana
|
||||
//
|
||||
// Created by QFish on 3/19/15.
|
||||
// Copyright (c) 2015 QFish. All rights reserved.
|
||||
//
|
||||
|
||||
#include "foundation.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
//#undef assert
|
||||
//#define assert(x)
|
||||
|
||||
struct KatanaInternalParser;
|
||||
|
||||
const KatanaParserString kKatanaAsteriskString = {"*", 1};
|
||||
|
||||
static const size_t kDefaultStringBufferSize = 12;
|
||||
|
||||
static void maybe_resize_string(struct KatanaInternalParser* parser,
|
||||
size_t additional_chars,
|
||||
KatanaParserString* str) {
|
||||
size_t new_length = str->length + additional_chars;
|
||||
size_t new_capacity = str->capacity;
|
||||
while (new_capacity < new_length) {
|
||||
new_capacity *= 2;
|
||||
}
|
||||
if (new_capacity != str->capacity) {
|
||||
char* new_data = katana_parser_allocate(parser, new_capacity);
|
||||
memset(new_data, 0, str->length);
|
||||
memcpy(new_data, str->data, str->length);
|
||||
katana_parser_deallocate(parser, str->data);
|
||||
str->data = new_data;
|
||||
str->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
void katana_string_init(struct KatanaInternalParser* parser,
|
||||
KatanaParserString* output) {
|
||||
output->data = katana_parser_allocate(parser, kDefaultStringBufferSize);
|
||||
memset( output->data, 0, sizeof(kDefaultStringBufferSize) );
|
||||
output->length = 0;
|
||||
output->capacity = kDefaultStringBufferSize;
|
||||
}
|
||||
|
||||
void katana_string_append_characters(struct KatanaInternalParser* parser,
|
||||
const char* str, KatanaParserString* output)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
maybe_resize_string(parser, len, output);
|
||||
memcpy(output->data + output->length, str, len);
|
||||
output->length += len;
|
||||
}
|
||||
|
||||
void katana_string_prepend_characters(struct KatanaInternalParser* parser,
|
||||
const char* str,
|
||||
KatanaParserString* output)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
size_t new_length = output->length + len;
|
||||
char* new_data = katana_parser_allocate(parser, new_length);
|
||||
memcpy(new_data, str, len);
|
||||
memcpy(new_data+len, output->data, output->length);
|
||||
katana_parser_deallocate(parser, output->data);
|
||||
output->data = new_data;
|
||||
output->length = new_length;
|
||||
output->capacity = new_length;
|
||||
}
|
||||
|
||||
void katana_string_append_string(struct KatanaInternalParser* parser,
|
||||
KatanaParserString* str,
|
||||
KatanaParserString* output) {
|
||||
maybe_resize_string(parser, str->length, output);
|
||||
memcpy(output->data + output->length, str->data, str->length);
|
||||
output->length += str->length;
|
||||
}
|
||||
|
||||
bool katana_string_has_prefix(const char* str, const char* prefix)
|
||||
{
|
||||
size_t pre_len = strlen(prefix);
|
||||
size_t str_len = strlen(str);
|
||||
return pre_len <= str_len && stricmp(prefix, str, pre_len);
|
||||
}
|
||||
|
||||
void katana_string_to_lowercase(struct KatanaInternalParser* parser,
|
||||
KatanaParserString* str)
|
||||
{
|
||||
if ( !str )
|
||||
return;
|
||||
// FIXME: @(QFish) the char* in string piece is const, to find a better way
|
||||
char *c = (char*)str->data;
|
||||
for (int i=0; i < str->length; i++) {
|
||||
*c = tolower(*c);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* katana_string_to_characters(struct KatanaInternalParser * parser, const KatanaParserString* str)
|
||||
{
|
||||
assert(NULL != str);
|
||||
if (NULL == str)
|
||||
return NULL;
|
||||
|
||||
char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 1));
|
||||
memcpy(buffer, str->data, str->length);
|
||||
buffer[str->length] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char* katana_string_to_characters_with_prefix_char(struct KatanaInternalParser * parser, const KatanaParserString* str, const char prefix)
|
||||
{
|
||||
assert(str);
|
||||
if (NULL == str)
|
||||
return NULL;
|
||||
|
||||
char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 2));
|
||||
memcpy((buffer + 1), str->data, str->length);
|
||||
buffer[0] = prefix;
|
||||
buffer[str->length] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array
|
||||
*/
|
||||
void katana_array_init(struct KatanaInternalParser* parser,
|
||||
size_t initial_capacity, KatanaArray* array) {
|
||||
array->length = 0;
|
||||
array->capacity = (unsigned int)initial_capacity;
|
||||
if (initial_capacity > 0) {
|
||||
array->data = katana_parser_allocate(parser, sizeof(void*) * initial_capacity);
|
||||
} else {
|
||||
array->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void katana_array_destroy(struct KatanaInternalParser* parser,
|
||||
KatanaArray* array) {
|
||||
if (array->capacity > 0) {
|
||||
katana_parser_deallocate(parser, array->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void enlarge_array_if_full(struct KatanaInternalParser* parser,
|
||||
KatanaArray* array) {
|
||||
if (array->length >= array->capacity) {
|
||||
if (array->capacity) {
|
||||
size_t old_num_bytes = sizeof(void*) * array->capacity;
|
||||
array->capacity *= 2;
|
||||
size_t num_bytes = sizeof(void*) * array->capacity;
|
||||
void** temp = katana_parser_allocate(parser, num_bytes);
|
||||
memcpy(temp, array->data, old_num_bytes);
|
||||
katana_parser_deallocate(parser, array->data);
|
||||
array->data = temp;
|
||||
} else {
|
||||
// 0-capacity array; no previous array to deallocate.
|
||||
array->capacity = 2;
|
||||
array->data = katana_parser_allocate(parser, sizeof(void*) * array->capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void katana_array_add(struct KatanaInternalParser* parser,
|
||||
void* element, KatanaArray* array) {
|
||||
enlarge_array_if_full(parser, array);
|
||||
assert(array->data);
|
||||
assert(array->length < array->capacity);
|
||||
array->data[array->length++] = element;
|
||||
}
|
||||
|
||||
void* katana_array_pop(struct KatanaInternalParser* parser,
|
||||
KatanaArray* array) {
|
||||
if (array->length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return array->data[--array->length];
|
||||
}
|
||||
|
||||
int katana_array_index_of(KatanaArray* array, void* element) {
|
||||
for (int i = 0; i < array->length; ++i) {
|
||||
if (array->data[i] == element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void katana_array_insert_at(struct KatanaInternalParser* parser,
|
||||
void* element, int index,
|
||||
KatanaArray* array) {
|
||||
assert(index >= 0);
|
||||
assert(index <= array->length);
|
||||
enlarge_array_if_full(parser, array);
|
||||
++array->length;
|
||||
memmove(&array->data[index + 1], &array->data[index],
|
||||
sizeof(void*) * (array->length - index - 1));
|
||||
array->data[index] = element;
|
||||
}
|
||||
|
||||
void katana_array_remove(struct KatanaInternalParser* parser,
|
||||
void* node, KatanaArray* array) {
|
||||
int index = katana_array_index_of(array, node);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
katana_array_remove_at(parser, index, array);
|
||||
}
|
||||
|
||||
void* katana_array_remove_at(struct KatanaInternalParser* parser,
|
||||
int index, KatanaArray* array) {
|
||||
assert(index >= 0);
|
||||
assert(index < array->length);
|
||||
void* result = array->data[index];
|
||||
memmove(&array->data[index], &array->data[index + 1],
|
||||
sizeof(void*) * (array->length - index - 1));
|
||||
--array->length;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alloc / free method
|
||||
*/
|
||||
void* katana_parser_allocate(struct KatanaInternalParser* parser, size_t size) {
|
||||
return parser->options->allocator(parser->options->userdata, size);
|
||||
}
|
||||
|
||||
void katana_parser_deallocate(struct KatanaInternalParser* parser, void* ptr) {
|
||||
parser->options->deallocator(parser->options->userdata, ptr);
|
||||
}
|
||||
129
Nuake/src/Vendors/katana-parser/foundation.h
Normal file
129
Nuake/src/Vendors/katana-parser/foundation.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __Katana__foundation__
|
||||
#define __Katana__foundation__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "katana.h"
|
||||
|
||||
struct KatanaInternalParser;
|
||||
|
||||
/**
|
||||
* Positon, for error debug
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int line;
|
||||
unsigned int column;
|
||||
unsigned int offset;
|
||||
} KatanaSourcePosition;
|
||||
|
||||
/**
|
||||
* String
|
||||
*/
|
||||
typedef struct {
|
||||
char* data;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
} KatanaParserString;
|
||||
|
||||
extern const KatanaParserString kKatanaAsteriskString;
|
||||
|
||||
void katana_string_to_lowercase(struct KatanaInternalParser* parser, KatanaParserString* string);
|
||||
|
||||
// Initializes a new KatanaParserString.
|
||||
void katana_string_init(struct KatanaInternalParser* parser, KatanaParserString* output);
|
||||
|
||||
// Appends some characters onto the end of the KatanaParserString.
|
||||
void katana_string_append_characters(struct KatanaInternalParser* parser, const char* str, KatanaParserString* output);
|
||||
|
||||
// Prepends some characters at the start of the KatanaParserString.
|
||||
void katana_string_prepend_characters(struct KatanaInternalParser* parser, const char* str, KatanaParserString* output);
|
||||
|
||||
// Transforms a KatanaParserString to characters.
|
||||
const char* katana_string_to_characters(struct KatanaInternalParser * parser, const KatanaParserString* str);
|
||||
// Transforms a KatanaParserString to characters with a char prepended at the start of the KatanaParserString.
|
||||
const char* katana_string_to_characters_with_prefix_char(struct KatanaInternalParser * parser, const KatanaParserString* str, const char prefix);
|
||||
|
||||
// Appends a string onto the end of the KatanaParserString.
|
||||
void katana_string_append_string(struct KatanaInternalParser* parser, KatanaParserString* str, KatanaParserString* output);
|
||||
// Returns a bool value that indicates whether a given string matches the beginning characters of the receiver.
|
||||
bool katana_string_has_prefix(const char* str, const char* prefix);
|
||||
|
||||
/**
|
||||
* Number
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaParserString raw;
|
||||
double val;
|
||||
} KatanaParserNumber;
|
||||
|
||||
/**
|
||||
* Array
|
||||
*/
|
||||
// Initializes a new KatanaArray with the specified initial capacity.
|
||||
void katana_array_init(struct KatanaInternalParser* parser, size_t initial_capacity,
|
||||
KatanaArray* array);
|
||||
|
||||
// Frees the memory used by an KatanaArray. Does not free the contained
|
||||
// pointers, but you should free the pointers if necessary.
|
||||
void katana_array_destroy(struct KatanaInternalParser* parser, KatanaArray* array);
|
||||
|
||||
// Adds a new element to an KatanaArray.
|
||||
void katana_array_add(struct KatanaInternalParser* parser, void* element, KatanaArray* array);
|
||||
|
||||
// Removes and returns the element most recently added to the KatanaArray.
|
||||
// Ownership is transferred to caller. Capacity is unchanged. If the array is
|
||||
// empty, NULL is returned.
|
||||
void* katana_array_pop(struct KatanaInternalParser* parser, KatanaArray* array);
|
||||
|
||||
// Inserts an element at a specific index. This is potentially O(N) time, but
|
||||
// is necessary for some of the spec's behavior.
|
||||
void katana_array_insert_at(struct KatanaInternalParser* parser, void* element, int index,
|
||||
KatanaArray* array);
|
||||
|
||||
// Removes an element from the array, or does nothing if the element is not in
|
||||
// the array.
|
||||
void katana_array_remove(struct KatanaInternalParser* parser, void* element, KatanaArray* array);
|
||||
|
||||
// Removes and returns an element at a specific index. Note that this is
|
||||
// potentially O(N) time and should be used sparingly.
|
||||
void* katana_array_remove_at(struct KatanaInternalParser* parser, int index, KatanaArray* array);
|
||||
|
||||
/**
|
||||
* An alloc / free method wrapper
|
||||
*/
|
||||
void* katana_parser_allocate(struct KatanaInternalParser* parser, size_t size);
|
||||
void katana_parser_deallocate(struct KatanaInternalParser* parser, void* ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* defined(__Katana__foundation__) */
|
||||
549
Nuake/src/Vendors/katana-parser/katana.h
Normal file
549
Nuake/src/Vendors/katana-parser/katana.h
Normal file
@@ -0,0 +1,549 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// CSS Spec: http://www.w3.org/TR/css-syntax-3/
|
||||
|
||||
#ifndef __Katana__katana__
|
||||
#define __Katana__katana__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define KATANA_ERROR_MESSAGE_SIZE 100
|
||||
|
||||
typedef enum {
|
||||
KatanaRuleUnkown,
|
||||
KatanaRuleStyle,
|
||||
KatanaRuleImport,
|
||||
KatanaRuleMedia,
|
||||
KatanaRuleFontFace,
|
||||
KatanaRuleSupports,
|
||||
KatanaRuleKeyframes,
|
||||
KatanaRuleCharset,
|
||||
KatanaRuleHost,
|
||||
} KatanaRuleType;
|
||||
|
||||
typedef enum {
|
||||
KatanaMediaQueryRestrictorNone,
|
||||
KatanaMediaQueryRestrictorOnly,
|
||||
KatanaMediaQueryRestrictorNot,
|
||||
} KatanaMediaQueryRestrictor;
|
||||
|
||||
typedef enum {
|
||||
KatanaSelectorMatchUnknown = 0,
|
||||
KatanaSelectorMatchTag, // Example: div
|
||||
KatanaSelectorMatchId, // Example: #id
|
||||
KatanaSelectorMatchClass, // example: .class
|
||||
KatanaSelectorMatchPseudoClass, // Example: :nth-child(2)
|
||||
KatanaSelectorMatchPseudoElement, // Example: ::first-line
|
||||
KatanaSelectorMatchPagePseudoClass, // ??
|
||||
KatanaSelectorMatchAttributeExact, // Example: E[foo="bar"]
|
||||
KatanaSelectorMatchAttributeSet, // Example: E[foo]
|
||||
KatanaSelectorMatchAttributeList, // Example: E[foo~="bar"]
|
||||
KatanaSelectorMatchAttributeHyphen, // Example: E[foo|="bar"]
|
||||
KatanaSelectorMatchAttributeContain, // css3: E[foo*="bar"]
|
||||
KatanaSelectorMatchAttributeBegin, // css3: E[foo^="bar"]
|
||||
KatanaSelectorMatchAttributeEnd, // css3: E[foo$="bar"]
|
||||
KatanaSelectorMatchFirstAttribute = KatanaSelectorMatchAttributeExact,
|
||||
} KatanaSelectorMatch;
|
||||
|
||||
typedef enum {
|
||||
KatanaSelectorRelationSubSelector, // "No space" combinator
|
||||
KatanaSelectorRelationDescendant, // "Space" combinator
|
||||
KatanaSelectorRelationChild, // > combinator
|
||||
KatanaSelectorRelationDirectAdjacent, // + combinator
|
||||
KatanaSelectorRelationIndirectAdjacent, // ~ combinator
|
||||
KatanaSelectorRelationShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
|
||||
KatanaSelectorRelationShadowDeep // /shadow-deep/ combinator
|
||||
} KatanaSelectorRelation;
|
||||
|
||||
typedef enum {
|
||||
KatanaPseudoNotParsed,
|
||||
KatanaPseudoUnknown,
|
||||
KatanaPseudoEmpty,
|
||||
KatanaPseudoFirstChild,
|
||||
KatanaPseudoFirstOfType,
|
||||
KatanaPseudoLastChild,
|
||||
KatanaPseudoLastOfType,
|
||||
KatanaPseudoOnlyChild,
|
||||
KatanaPseudoOnlyOfType,
|
||||
KatanaPseudoFirstLine,
|
||||
KatanaPseudoFirstLetter,
|
||||
KatanaPseudoNthChild,
|
||||
KatanaPseudoNthOfType,
|
||||
KatanaPseudoNthLastChild,
|
||||
KatanaPseudoNthLastOfType,
|
||||
KatanaPseudoLink,
|
||||
KatanaPseudoVisited,
|
||||
KatanaPseudoAny,
|
||||
KatanaPseudoAnyLink,
|
||||
KatanaPseudoAutofill,
|
||||
KatanaPseudoHover,
|
||||
KatanaPseudoDrag,
|
||||
KatanaPseudoFocus,
|
||||
KatanaPseudoActive,
|
||||
KatanaPseudoChecked,
|
||||
KatanaPseudoEnabled,
|
||||
KatanaPseudoFullPageMedia,
|
||||
KatanaPseudoDefault,
|
||||
KatanaPseudoDisabled,
|
||||
KatanaPseudoOptional,
|
||||
KatanaPseudoRequired,
|
||||
KatanaPseudoReadOnly,
|
||||
KatanaPseudoReadWrite,
|
||||
KatanaPseudoValid,
|
||||
KatanaPseudoInvalid,
|
||||
KatanaPseudoIndeterminate,
|
||||
KatanaPseudoTarget,
|
||||
KatanaPseudoBefore,
|
||||
KatanaPseudoAfter,
|
||||
KatanaPseudoBackdrop,
|
||||
KatanaPseudoLang,
|
||||
KatanaPseudoNot, // :not(selector), selector is Kind of KatanaSelector
|
||||
KatanaPseudoResizer,
|
||||
KatanaPseudoRoot,
|
||||
KatanaPseudoScope,
|
||||
KatanaPseudoScrollbar,
|
||||
KatanaPseudoScrollbarButton,
|
||||
KatanaPseudoScrollbarCorner,
|
||||
KatanaPseudoScrollbarThumb,
|
||||
KatanaPseudoScrollbarTrack,
|
||||
KatanaPseudoScrollbarTrackPiece,
|
||||
KatanaPseudoWindowInactive,
|
||||
KatanaPseudoCornerPresent,
|
||||
KatanaPseudoDecrement,
|
||||
KatanaPseudoIncrement,
|
||||
KatanaPseudoHorizontal,
|
||||
KatanaPseudoVertical,
|
||||
KatanaPseudoStart,
|
||||
KatanaPseudoEnd,
|
||||
KatanaPseudoDoubleButton,
|
||||
KatanaPseudoSingleButton,
|
||||
KatanaPseudoNoButton,
|
||||
KatanaPseudoSelection,
|
||||
KatanaPseudoLeftPage,
|
||||
KatanaPseudoRightPage,
|
||||
KatanaPseudoFirstPage,
|
||||
KatanaPseudoFullScreen,
|
||||
KatanaPseudoFullScreenDocument,
|
||||
KatanaPseudoFullScreenAncestor,
|
||||
KatanaPseudoInRange,
|
||||
KatanaPseudoOutOfRange,
|
||||
KatanaPseudoWebKitCustomElement,
|
||||
KatanaPseudoCue,
|
||||
KatanaPseudoFutureCue,
|
||||
KatanaPseudoPastCue,
|
||||
KatanaPseudoUnresolved,
|
||||
KatanaPseudoContent,
|
||||
KatanaPseudoHost,
|
||||
KatanaPseudoHostContext,
|
||||
KatanaPseudoShadow,
|
||||
KatanaPseudoSpatialNavigationFocus,
|
||||
KatanaPseudoListBox
|
||||
} KatanaPseudoType;
|
||||
|
||||
typedef enum {
|
||||
KatanaAttributeMatchTypeCaseSensitive,
|
||||
KatanaAttributeMatchTypeCaseInsensitive,
|
||||
} KatanaAttributeMatchType;
|
||||
|
||||
typedef enum {
|
||||
KATANA_VALUE_UNKNOWN = 0,
|
||||
KATANA_VALUE_NUMBER = 1,
|
||||
KATANA_VALUE_PERCENTAGE = 2,
|
||||
KATANA_VALUE_EMS = 3,
|
||||
KATANA_VALUE_EXS = 4,
|
||||
|
||||
// double
|
||||
KATANA_VALUE_PX = 5,
|
||||
KATANA_VALUE_CM = 6,
|
||||
KATANA_VALUE_MM = 7,
|
||||
KATANA_VALUE_IN = 8,
|
||||
KATANA_VALUE_PT = 9,
|
||||
KATANA_VALUE_PC = 10,
|
||||
KATANA_VALUE_DEG = 11,
|
||||
KATANA_VALUE_RAD = 12,
|
||||
KATANA_VALUE_GRAD = 13,
|
||||
KATANA_VALUE_MS = 14,
|
||||
KATANA_VALUE_S = 15,
|
||||
KATANA_VALUE_HZ = 16,
|
||||
KATANA_VALUE_KHZ = 17,
|
||||
KATANA_VALUE_DIMENSION = 18,
|
||||
KATANA_VALUE_STRING = 19,
|
||||
KATANA_VALUE_URI = 20,
|
||||
KATANA_VALUE_IDENT = 21,
|
||||
KATANA_VALUE_ATTR = 22,
|
||||
KATANA_VALUE_COUNTER = 23,
|
||||
KATANA_VALUE_RECT = 24,
|
||||
KATANA_VALUE_RGBCOLOR = 25,
|
||||
|
||||
KATANA_VALUE_VW = 26,
|
||||
KATANA_VALUE_VH = 27,
|
||||
KATANA_VALUE_VMIN = 28,
|
||||
KATANA_VALUE_VMAX = 29,
|
||||
KATANA_VALUE_DPPX = 30,
|
||||
KATANA_VALUE_DPI = 31,
|
||||
KATANA_VALUE_DPCM = 32,
|
||||
KATANA_VALUE_FR = 33,
|
||||
KATANA_VALUE_UNICODE_RANGE = 102,
|
||||
|
||||
KATANA_VALUE_PARSER_OPERATOR = 103,
|
||||
KATANA_VALUE_PARSER_INTEGER = 104,
|
||||
KATANA_VALUE_PARSER_HEXCOLOR = 105,
|
||||
KATANA_VALUE_PARSER_FUNCTION = 0x100001,
|
||||
KATANA_VALUE_PARSER_LIST = 0x100002,
|
||||
KATANA_VALUE_PARSER_Q_EMS = 0x100003,
|
||||
|
||||
KATANA_VALUE_PARSER_IDENTIFIER = 106,
|
||||
|
||||
KATANA_VALUE_TURN = 107,
|
||||
KATANA_VALUE_REMS = 108,
|
||||
KATANA_VALUE_CHS = 109,
|
||||
|
||||
KATANA_VALUE_COUNTER_NAME = 110,
|
||||
|
||||
KATANA_VALUE_SHAPE = 111,
|
||||
|
||||
KATANA_VALUE_QUAD = 112,
|
||||
|
||||
KATANA_VALUE_CALC = 113,
|
||||
KATANA_VALUE_CALC_PERCENTAGE_WITH_NUMBER = 114,
|
||||
KATANA_VALUE_CALC_PERCENTAGE_WITH_LENGTH = 115,
|
||||
KATANA_VALUE_VARIABLE_NAME = 116,
|
||||
|
||||
KATANA_VALUE_PROPERTY_ID = 117,
|
||||
KATANA_VALUE_VALUE_ID = 118
|
||||
} KatanaValueUnit;
|
||||
|
||||
//typedef enum {
|
||||
// KATANA_VALUE_PARSER_OPERATOR = 0x100000,
|
||||
// KATANA_VALUE_PARSER_FUNCTION = 0x100001,
|
||||
// KATANA_VALUE_PARSER_LIST = 0x100002,
|
||||
// KATANA_VALUE_PARSER_Q_EMS = 0x100003,
|
||||
//} KatanaParserValueUnit;
|
||||
|
||||
typedef enum {
|
||||
KatanaValueInvalid = 0,
|
||||
KatanaValueInherit = 1,
|
||||
KatanaValueInitial = 2,
|
||||
KatanaValueNone = 3,
|
||||
KatanaValueCustom = 0x100010,
|
||||
} KatanaValueID;
|
||||
|
||||
typedef enum { KatanaParseError } KatanaErrorType;
|
||||
|
||||
typedef struct {
|
||||
const char* local; // tag local name
|
||||
const char* prefix; // namesapce identifier
|
||||
const char* uri; // namesapce uri
|
||||
} KatanaQualifiedName;
|
||||
|
||||
typedef struct {
|
||||
/** Data elements. This points to a dynamically-allocated array of capacity
|
||||
* elements, each a void* to the element itself, remember free each element.
|
||||
*/
|
||||
void** data;
|
||||
|
||||
/** Number of elements currently in the array. */
|
||||
unsigned int length;
|
||||
|
||||
/** Current array capacity. */
|
||||
unsigned int capacity;
|
||||
|
||||
} KatanaArray;
|
||||
|
||||
typedef struct {
|
||||
const char* encoding;
|
||||
KatanaArray /* KatanaRule */ rules;
|
||||
KatanaArray /* KatanaImportRule */ imports;
|
||||
} KatanaStylesheet;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
KatanaRuleType type;
|
||||
} KatanaRule;
|
||||
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
KatanaArray* /* KatanaSelector */ selectors;
|
||||
KatanaArray* /* KatanaDeclaration */ declarations;
|
||||
} KatanaStyleRule;
|
||||
|
||||
typedef struct {
|
||||
const char* comment;
|
||||
} KatanaComment; // unused for right
|
||||
|
||||
/**
|
||||
* The `@font-face` at-rule.
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
KatanaArray* /* KatanaDeclaration */ declarations;
|
||||
} KatanaFontFaceRule;
|
||||
|
||||
/**
|
||||
* The `@host` at-rule.
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
KatanaArray* /* KatanaRule */ host;
|
||||
} KatanaHostRule;
|
||||
|
||||
/**
|
||||
* The `@import` at-rule.
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
/**
|
||||
* The part following `@import `
|
||||
*/
|
||||
const char* href;
|
||||
/**
|
||||
* The media list belonging to this import rule
|
||||
*/
|
||||
KatanaArray* /* KatanaMediaQuery* */ medias;
|
||||
} KatanaImportRule;
|
||||
|
||||
/**
|
||||
* The `@keyframes` at-rule.
|
||||
* Spec: http://www.w3.org/TR/css3-animations/#keyframes
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
/**
|
||||
* The vendor prefix in `@keyframes`, or `undefined` if there is none.
|
||||
*/
|
||||
const char* name;
|
||||
KatanaArray* /* KatanaKeyframe */ keyframes;
|
||||
} KatanaKeyframesRule;
|
||||
|
||||
typedef struct {
|
||||
KatanaArray* /* KatanaValue: `percentage`, `from`, `to` */ selectors;
|
||||
KatanaArray* /* KatanaDeclaration */ declarations;
|
||||
} KatanaKeyframe;
|
||||
|
||||
/**
|
||||
* The `@media` at-rule.
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
/**
|
||||
* The part following `@media `
|
||||
*/
|
||||
KatanaArray* medias;
|
||||
/**
|
||||
* An `Array` of nodes with the types `rule`, `comment` and any of the
|
||||
at-rule types.
|
||||
*/
|
||||
KatanaArray* /* KatanaRule */ rules;
|
||||
} KatanaMediaRule;
|
||||
|
||||
/**
|
||||
* Media Query Exp List
|
||||
* Spec: http://www.w3.org/TR/mediaqueries-4/
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
KatanaMediaQueryRestrictor restrictor;
|
||||
const char* type;
|
||||
KatanaArray* expressions;
|
||||
bool ignored;
|
||||
} KatanaMediaQuery;
|
||||
|
||||
typedef struct {
|
||||
const char* feature;
|
||||
KatanaArray* values;
|
||||
const char* raw;
|
||||
} KatanaMediaQueryExp;
|
||||
|
||||
typedef struct {
|
||||
const char* value;
|
||||
union {
|
||||
struct {
|
||||
int a; // Used for :nth-*
|
||||
int b; // Used for :nth-*
|
||||
} nth;
|
||||
KatanaAttributeMatchType attributeMatchType; // used for attribute selector (with value)
|
||||
} bits;
|
||||
KatanaQualifiedName* attribute;
|
||||
const char* argument; // Used for :contains, :lang, :nth-*
|
||||
KatanaArray* selectors; // Used for :any and :not
|
||||
} KatanaSelectorRareData;
|
||||
|
||||
typedef struct KatanaSelector {
|
||||
size_t specificity;
|
||||
KatanaSelectorMatch match;
|
||||
KatanaPseudoType pseudo;
|
||||
KatanaSelectorRelation relation;
|
||||
KatanaQualifiedName* tag;
|
||||
KatanaSelectorRareData* data;
|
||||
struct KatanaSelector* tagHistory;
|
||||
} KatanaSelector;
|
||||
|
||||
unsigned katana_calc_specificity_for_selector(KatanaSelector* selector);
|
||||
|
||||
typedef struct {
|
||||
// property name
|
||||
const char* property;
|
||||
|
||||
// property value
|
||||
KatanaArray* /* KatanaValue */ values;
|
||||
const char* string;
|
||||
|
||||
// is this property marked important
|
||||
bool important;
|
||||
|
||||
// origin css text of the property
|
||||
const char* raw;
|
||||
} KatanaDeclaration;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
KatanaArray* args;
|
||||
} KatanaValueFunction;
|
||||
|
||||
typedef struct KatanaValue {
|
||||
KatanaValueID id;
|
||||
bool isInt;
|
||||
union {
|
||||
int iValue;
|
||||
double fValue;
|
||||
const char* string;
|
||||
KatanaValueFunction* function;
|
||||
KatanaArray* list;
|
||||
};
|
||||
KatanaValueUnit unit;
|
||||
const char* raw;
|
||||
} KatanaValue;
|
||||
|
||||
/**
|
||||
* The `@charset` at-rule.
|
||||
*/
|
||||
typedef struct {
|
||||
KatanaRule base;
|
||||
/**
|
||||
* The encoding information
|
||||
*/
|
||||
const char* encoding;
|
||||
} KatanaCharsetRule;
|
||||
|
||||
typedef struct {
|
||||
KatanaErrorType type;
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
char message[KATANA_ERROR_MESSAGE_SIZE];
|
||||
} KatanaError;
|
||||
|
||||
// TODO: @document
|
||||
// TODO: @page
|
||||
// TODO: @supports
|
||||
// TODO: custom-at-rule
|
||||
|
||||
/**
|
||||
* Parser mode
|
||||
*/
|
||||
typedef enum KatanaParserMode {
|
||||
// Normal CSS content used in External CSS files or Internal CSS, may include more than 1 css rules.
|
||||
KatanaParserModeStylesheet,
|
||||
|
||||
// Single CSS rule like "@import", "selector{...}"
|
||||
KatanaParserModeRule,
|
||||
|
||||
KatanaParserModeKeyframeRule,
|
||||
KatanaParserModeKeyframeKeyList,
|
||||
KatanaParserModeMediaList,
|
||||
|
||||
// CSS property value like "1px", "1em", "#eee"
|
||||
KatanaParserModeValue,
|
||||
|
||||
// CSS selector like ".pages.active"
|
||||
KatanaParserModeSelector,
|
||||
|
||||
// Inline stylesheet like "width: 20px; height: 20px;"
|
||||
KatanaParserModeDeclarationList,
|
||||
} KatanaParserMode;
|
||||
|
||||
typedef struct KatanaInternalOutput {
|
||||
// Complete CSS string
|
||||
KatanaStylesheet* stylesheet;
|
||||
union {
|
||||
// fragmental CSS string
|
||||
KatanaRule* rule;
|
||||
KatanaKeyframe* keyframe;
|
||||
KatanaArray* keyframe_keys;
|
||||
KatanaArray* values;
|
||||
KatanaArray* medias;
|
||||
KatanaArray* /* KatanaDeclaration */ declarations;
|
||||
KatanaArray* selectors;
|
||||
};
|
||||
KatanaParserMode mode;
|
||||
KatanaArray /* KatanaError */ errors;
|
||||
} KatanaOutput;
|
||||
|
||||
/**
|
||||
* Parse a complete or fragmental CSS string
|
||||
*
|
||||
* @param str Input CSS string
|
||||
* @param len Length of the input CSS string
|
||||
* @param mode Parser mode, depends on the input
|
||||
*
|
||||
* @return The result of parsing
|
||||
*/
|
||||
KatanaOutput* katana_parse(const char* str, size_t len, KatanaParserMode mode);
|
||||
|
||||
/**
|
||||
* Parse a complete CSS file
|
||||
*
|
||||
* @param fp `FILE` point to the CSS file
|
||||
*
|
||||
* @return The result of parsing
|
||||
*/
|
||||
KatanaOutput* katana_parse_in(FILE* fp);
|
||||
|
||||
/**
|
||||
* Free the output
|
||||
*
|
||||
* @param output The result of parsing
|
||||
*/
|
||||
void katana_destroy_output(KatanaOutput* output);
|
||||
|
||||
/**
|
||||
* Print the formatted CSS string
|
||||
*
|
||||
* @param output The result of parsing
|
||||
*
|
||||
* @return The origin output
|
||||
*/
|
||||
KatanaOutput* katana_dump_output(KatanaOutput* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(__Katana__katana__) */
|
||||
3750
Nuake/src/Vendors/katana-parser/katana.lex.c
Normal file
3750
Nuake/src/Vendors/katana-parser/katana.lex.c
Normal file
File diff suppressed because it is too large
Load Diff
354
Nuake/src/Vendors/katana-parser/katana.lex.h
Normal file
354
Nuake/src/Vendors/katana-parser/katana.lex.h
Normal file
@@ -0,0 +1,354 @@
|
||||
#include "katana.tab.h"
|
||||
|
||||
/* Substitute the type names. */
|
||||
#define YYSTYPE KATANASTYPE
|
||||
#define YYLTYPE KATANALTYPE
|
||||
|
||||
#ifndef katanaHEADER_H
|
||||
#define katanaHEADER_H 1
|
||||
#define katanaIN_HEADER 1
|
||||
|
||||
// #line 6 "katana.lex.h"
|
||||
|
||||
#define YY_INT_ALIGNED short int
|
||||
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 5
|
||||
#define YY_FLEX_SUBMINOR_VERSION 37
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* end standard C headers. */
|
||||
|
||||
/* flex integer type definitions */
|
||||
|
||||
#ifndef FLEXINT_H
|
||||
#define FLEXINT_H
|
||||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
#define INT8_MIN (-128)
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
#ifndef INT8_MAX
|
||||
#define INT8_MAX (127)
|
||||
#endif
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX (32767)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (255U)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (65535U)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#endif /* ! C99 */
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* The "const" storage-class-modifier is valid. */
|
||||
#define YY_USE_CONST
|
||||
|
||||
#else /* ! __cplusplus */
|
||||
|
||||
/* C99 requires __STDC__ to be defined as 1. */
|
||||
#if defined (__STDC__)
|
||||
|
||||
#define YY_USE_CONST
|
||||
|
||||
#endif /* defined (__STDC__) */
|
||||
#endif /* ! __cplusplus */
|
||||
|
||||
#ifdef YY_USE_CONST
|
||||
#define yyconst const
|
||||
#else
|
||||
#define yyconst
|
||||
#endif
|
||||
|
||||
/* An opaque pointer. */
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
/* For convenience, these vars (plus the bison vars far below)
|
||||
are macros in the reentrant scanner. */
|
||||
#define yyin yyg->yyin_r
|
||||
#define yyout yyg->yyout_r
|
||||
#define yyextra yyg->yyextra_r
|
||||
#define yyleng yyg->yyleng_r
|
||||
#define yytext yyg->yytext_r
|
||||
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
|
||||
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
|
||||
#define yy_flex_debug yyg->yy_flex_debug_r
|
||||
|
||||
/* Size of default input buffer. */
|
||||
#ifndef YY_BUF_SIZE
|
||||
#define YY_BUF_SIZE 16384
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
#define YY_TYPEDEF_YY_SIZE_T
|
||||
typedef size_t yy_size_t;
|
||||
#endif
|
||||
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
{
|
||||
FILE *yy_input_file;
|
||||
|
||||
char *yy_ch_buf; /* input buffer */
|
||||
char *yy_buf_pos; /* current position in input buffer */
|
||||
|
||||
/* Size of input buffer in bytes, not including room for EOB
|
||||
* characters.
|
||||
*/
|
||||
yy_size_t yy_buf_size;
|
||||
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
yy_size_t yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
* delete it.
|
||||
*/
|
||||
int yy_is_our_buffer;
|
||||
|
||||
/* Whether this is an "interactive" input source; if so, and
|
||||
* if we're using stdio for input, then we want to use getc()
|
||||
* instead of fread(), to make sure we stop fetching input after
|
||||
* each newline.
|
||||
*/
|
||||
int yy_is_interactive;
|
||||
|
||||
/* Whether we're considered to be at the beginning of a line.
|
||||
* If so, '^' rules will be active on the next match, otherwise
|
||||
* not.
|
||||
*/
|
||||
int yy_at_bol;
|
||||
|
||||
int yy_bs_lineno; /**< The line count. */
|
||||
int yy_bs_column; /**< The column count. */
|
||||
|
||||
/* Whether to try to fill the input buffer when we reach the
|
||||
* end of it.
|
||||
*/
|
||||
int yy_fill_buffer;
|
||||
|
||||
int yy_buffer_status;
|
||||
|
||||
};
|
||||
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
|
||||
|
||||
void katanarestart (FILE *input_file ,yyscan_t yyscanner );
|
||||
void katana_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE katana_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
|
||||
void katana_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void katana_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void katanapush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
void katanapop_buffer_state (yyscan_t yyscanner );
|
||||
|
||||
YY_BUFFER_STATE katana_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE katana_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE katana_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
|
||||
|
||||
void *katanaalloc (yy_size_t ,yyscan_t yyscanner );
|
||||
void *katanarealloc (void *,yy_size_t ,yyscan_t yyscanner );
|
||||
void katanafree (void * ,yyscan_t yyscanner );
|
||||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define katanawrap(yyscanner) 1
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
#define yytext_ptr yytext_r
|
||||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
#define mediaquery 1
|
||||
#define supports 2
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_UNISTD_H
|
||||
/* Special case for "unistd.h", since it is non-ANSI. We include it way
|
||||
* down here because we want the user's section 1 to have been scanned first.
|
||||
* The user has a chance to override it with an option.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_EXTRA_TYPE
|
||||
#define YY_EXTRA_TYPE void *
|
||||
#endif
|
||||
|
||||
int katanalex_init (yyscan_t* scanner);
|
||||
|
||||
int katanalex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
|
||||
|
||||
/* Accessor methods to globals.
|
||||
These are made visible to non-reentrant scanners for convenience. */
|
||||
|
||||
int katanalex_destroy (yyscan_t yyscanner );
|
||||
|
||||
int katanaget_debug (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_debug (int debug_flag ,yyscan_t yyscanner );
|
||||
|
||||
YY_EXTRA_TYPE katanaget_extra (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
|
||||
|
||||
FILE *katanaget_in (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_in (FILE * in_str ,yyscan_t yyscanner );
|
||||
|
||||
FILE *katanaget_out (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_out (FILE * out_str ,yyscan_t yyscanner );
|
||||
|
||||
yy_size_t katanaget_leng (yyscan_t yyscanner );
|
||||
|
||||
char *katanaget_text (yyscan_t yyscanner );
|
||||
|
||||
int katanaget_lineno (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_lineno (int line_number ,yyscan_t yyscanner );
|
||||
|
||||
int katanaget_column (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_column (int column_no ,yyscan_t yyscanner );
|
||||
|
||||
YYSTYPE * katanaget_lval (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
|
||||
|
||||
YYLTYPE *katanaget_lloc (yyscan_t yyscanner );
|
||||
|
||||
void katanaset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
|
||||
#ifndef YY_SKIP_YYWRAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" int katanawrap (yyscan_t yyscanner );
|
||||
#else
|
||||
extern int katanawrap (yyscan_t yyscanner );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifdef YY_NEED_STRLEN
|
||||
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
|
||||
#endif
|
||||
|
||||
/* Amount of stuff to slurp up with each read. */
|
||||
#ifndef YY_READ_BUF_SIZE
|
||||
#define YY_READ_BUF_SIZE 8192
|
||||
#endif
|
||||
|
||||
/* Number of entries by which start-condition stack grows. */
|
||||
#ifndef YY_START_STACK_INCR
|
||||
#define YY_START_STACK_INCR 25
|
||||
#endif
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
#ifndef YY_DECL
|
||||
#define YY_DECL_IS_OURS 1
|
||||
|
||||
extern int katanalex \
|
||||
(YYSTYPE* yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser);
|
||||
|
||||
#define YY_DECL int katanalex \
|
||||
(YYSTYPE * yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser)
|
||||
|
||||
#endif /* !YY_DECL */
|
||||
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
//#undef YY_NEW_FILE
|
||||
#undef YY_FLUSH_BUFFER
|
||||
#undef yy_set_bol
|
||||
#undef yy_new_buffer
|
||||
#undef yy_set_interactive
|
||||
//#undef YY_DO_BEFORE_ACTION
|
||||
|
||||
#ifdef YY_DECL_IS_OURS
|
||||
#undef YY_DECL_IS_OURS
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
// #line 346 "katana.lex.h"
|
||||
#undef katanaIN_HEADER
|
||||
#endif /* katanaHEADER_H */
|
||||
4323
Nuake/src/Vendors/katana-parser/katana.tab.c
Normal file
4323
Nuake/src/Vendors/katana-parser/katana.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
235
Nuake/src/Vendors/katana-parser/katana.tab.h
Normal file
235
Nuake/src/Vendors/katana-parser/katana.tab.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_KATANA_KATANA_TAB_H_INCLUDED
|
||||
# define YY_KATANA_KATANA_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef KATANADEBUG
|
||||
# if defined YYDEBUG
|
||||
#if YYDEBUG
|
||||
# define KATANADEBUG 1
|
||||
# else
|
||||
# define KATANADEBUG 0
|
||||
# endif
|
||||
# else /* ! defined YYDEBUG */
|
||||
# define KATANADEBUG 1
|
||||
# endif /* ! defined YYDEBUG */
|
||||
#endif /* ! defined KATANADEBUG */
|
||||
#if KATANADEBUG
|
||||
extern int katanadebug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
|
||||
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
|
||||
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
|
||||
* Copyright (C) 2012 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2015 QFish (im@qfi.sh)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "foundation.h"
|
||||
#include "katana.h"
|
||||
|
||||
|
||||
|
||||
/* Token type. */
|
||||
#ifndef KATANATOKENTYPE
|
||||
# define KATANATOKENTYPE
|
||||
enum katanatokentype
|
||||
{
|
||||
TOKEN_EOF = 0,
|
||||
LOWEST_PREC = 258,
|
||||
UNIMPORTANT_TOK = 259,
|
||||
KATANA_CSS_SGML_CD = 260,
|
||||
KATANA_CSS_WHITESPACE = 261,
|
||||
KATANA_CSS_INCLUDES = 262,
|
||||
KATANA_CSS_DASHMATCH = 263,
|
||||
KATANA_CSS_BEGINSWITH = 264,
|
||||
KATANA_CSS_ENDSWITH = 265,
|
||||
KATANA_CSS_CONTAINS = 266,
|
||||
KATANA_CSS_STRING = 267,
|
||||
KATANA_CSS_IDENT = 268,
|
||||
KATANA_CSS_NTH = 269,
|
||||
KATANA_CSS_HEX = 270,
|
||||
KATANA_CSS_IDSEL = 271,
|
||||
KATANA_CSS_IMPORT_SYM = 272,
|
||||
KATANA_CSS_PAGE_SYM = 273,
|
||||
KATANA_CSS_MEDIA_SYM = 274,
|
||||
KATANA_CSS_SUPPORTS_SYM = 275,
|
||||
KATANA_CSS_FONT_FACE_SYM = 276,
|
||||
KATANA_CSS_CHARSET_SYM = 277,
|
||||
KATANA_CSS_NAMESPACE_SYM = 278,
|
||||
KATANA_INTERNAL_DECLS_SYM = 279,
|
||||
KATANA_INTERNAL_MEDIALIST_SYM = 280,
|
||||
KATANA_INTERNAL_RULE_SYM = 281,
|
||||
KATANA_INTERNAL_SELECTOR_SYM = 282,
|
||||
KATANA_INTERNAL_VALUE_SYM = 283,
|
||||
KATANA_INTERNAL_KEYFRAME_RULE_SYM = 284,
|
||||
KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM = 285,
|
||||
KATANA_INTERNAL_SUPPORTS_CONDITION_SYM = 286,
|
||||
KATANA_CSS_KEYFRAMES_SYM = 287,
|
||||
KATANA_CSS_ATKEYWORD = 288,
|
||||
KATANA_CSS_IMPORTANT_SYM = 289,
|
||||
KATANA_CSS_MEDIA_NOT = 290,
|
||||
KATANA_CSS_MEDIA_ONLY = 291,
|
||||
KATANA_CSS_MEDIA_AND = 292,
|
||||
KATANA_CSS_MEDIA_OR = 293,
|
||||
KATANA_CSS_SUPPORTS_NOT = 294,
|
||||
KATANA_CSS_SUPPORTS_AND = 295,
|
||||
KATANA_CSS_SUPPORTS_OR = 296,
|
||||
KATANA_CSS_REMS = 297,
|
||||
KATANA_CSS_CHS = 298,
|
||||
KATANA_CSS_QEMS = 299,
|
||||
KATANA_CSS_EMS = 300,
|
||||
KATANA_CSS_EXS = 301,
|
||||
KATANA_CSS_PXS = 302,
|
||||
KATANA_CSS_CMS = 303,
|
||||
KATANA_CSS_MMS = 304,
|
||||
KATANA_CSS_INS = 305,
|
||||
KATANA_CSS_PTS = 306,
|
||||
KATANA_CSS_PCS = 307,
|
||||
KATANA_CSS_DEGS = 308,
|
||||
KATANA_CSS_RADS = 309,
|
||||
KATANA_CSS_GRADS = 310,
|
||||
KATANA_CSS_TURNS = 311,
|
||||
KATANA_CSS_MSECS = 312,
|
||||
KATANA_CSS_SECS = 313,
|
||||
KATANA_CSS_HERTZ = 314,
|
||||
KATANA_CSS_KHERTZ = 315,
|
||||
KATANA_CSS_DIMEN = 316,
|
||||
KATANA_CSS_INVALIDDIMEN = 317,
|
||||
KATANA_CSS_PERCENTAGE = 318,
|
||||
KATANA_CSS_FLOATTOKEN = 319,
|
||||
KATANA_CSS_INTEGER = 320,
|
||||
KATANA_CSS_VW = 321,
|
||||
KATANA_CSS_VH = 322,
|
||||
KATANA_CSS_VMIN = 323,
|
||||
KATANA_CSS_VMAX = 324,
|
||||
KATANA_CSS_DPPX = 325,
|
||||
KATANA_CSS_DPI = 326,
|
||||
KATANA_CSS_DPCM = 327,
|
||||
KATANA_CSS_FR = 328,
|
||||
KATANA_CSS_URI = 329,
|
||||
KATANA_CSS_FUNCTION = 330,
|
||||
KATANA_CSS_ANYFUNCTION = 331,
|
||||
KATANA_CSS_CUEFUNCTION = 332,
|
||||
KATANA_CSS_NOTFUNCTION = 333,
|
||||
KATANA_CSS_CALCFUNCTION = 334,
|
||||
KATANA_CSS_MINFUNCTION = 335,
|
||||
KATANA_CSS_MAXFUNCTION = 336,
|
||||
KATANA_CSS_HOSTFUNCTION = 337,
|
||||
KATANA_CSS_HOSTCONTEXTFUNCTION = 338,
|
||||
KATANA_CSS_UNICODERANGE = 339
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined KATANASTYPE && ! defined KATANASTYPE_IS_DECLARED
|
||||
|
||||
union KATANASTYPE
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool boolean;
|
||||
char character;
|
||||
int integer;
|
||||
KatanaParserNumber number;
|
||||
KatanaParserString string;
|
||||
|
||||
KatanaRule* rule;
|
||||
// The content of the three below HeapVectors are guaranteed to be kept alive by
|
||||
// the corresponding parsedRules, floatingMediaQueryExpList, and parsedKeyFrames
|
||||
// lists
|
||||
KatanaArray* ruleList;
|
||||
KatanaArray* mediaQueryExpList;
|
||||
KatanaArray* keyframeRuleList;
|
||||
|
||||
KatanaSelector* selector;
|
||||
KatanaArray* selectorList;
|
||||
// CSSSelector::MarginBoxType marginBox;
|
||||
KatanaSelectorRelation relation;
|
||||
KatanaAttributeMatchType attributeMatchType;
|
||||
KatanaArray* mediaList;
|
||||
KatanaMediaQuery* mediaQuery;
|
||||
KatanaMediaQueryRestrictor mediaQueryRestrictor;
|
||||
KatanaMediaQueryExp* mediaQueryExp;
|
||||
KatanaValue* value;
|
||||
KatanaArray* valueList;
|
||||
KatanaKeyframe* keyframe;
|
||||
KatanaSourcePosition* location;
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef union KATANASTYPE KATANASTYPE;
|
||||
# define KATANASTYPE_IS_TRIVIAL 1
|
||||
# define KATANASTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
/* Location type. */
|
||||
#if ! defined KATANALTYPE && ! defined KATANALTYPE_IS_DECLARED
|
||||
typedef struct KATANALTYPE KATANALTYPE;
|
||||
struct KATANALTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
};
|
||||
# define KATANALTYPE_IS_DECLARED 1
|
||||
# define KATANALTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int katanaparse (void* scanner, struct KatanaInternalParser * parser);
|
||||
|
||||
#endif /* !YY_KATANA_KATANA_TAB_H_INCLUDED */
|
||||
1720
Nuake/src/Vendors/katana-parser/parser.c
Normal file
1720
Nuake/src/Vendors/katana-parser/parser.c
Normal file
File diff suppressed because it is too large
Load Diff
250
Nuake/src/Vendors/katana-parser/parser.h
Normal file
250
Nuake/src/Vendors/katana-parser/parser.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __Katana__parser__
|
||||
#define __Katana__parser__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "katana.lex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define KATANA_FELX_DEBUG 0
|
||||
#define KATANA_BISON_DEBUG 0
|
||||
#define KATANA_PARSER_DEBUG 0
|
||||
#define KATANA_PARSER_LOG_ENABLE 0
|
||||
|
||||
|
||||
struct KatanaInternalOutput;
|
||||
struct KatanaInternalOptions;
|
||||
|
||||
typedef void* (*KatanaAllocatorFunction)(void* userdata, size_t size);
|
||||
|
||||
typedef void (*KatanaDeallocatorFunction)(void* userdata, void* ptr);
|
||||
|
||||
typedef struct KatanaInternalOptions {
|
||||
KatanaAllocatorFunction allocator;
|
||||
KatanaDeallocatorFunction deallocator;
|
||||
void* userdata;
|
||||
} KatanaOptions;
|
||||
|
||||
extern const KatanaOptions kKatanaDefaultOptions;
|
||||
|
||||
typedef struct KatanaInternalParser {
|
||||
// Settings for this parse run.
|
||||
const struct KatanaInternalOptions* options;
|
||||
|
||||
// Output for the parse.
|
||||
struct KatanaInternalOutput* output;
|
||||
|
||||
// The flex tokenizer info
|
||||
yyscan_t* scanner;
|
||||
|
||||
// The floating declarations
|
||||
KatanaArray* parsed_declarations;
|
||||
#if KATANA_PARSER_DEBUG
|
||||
// The floating selectors
|
||||
KatanaArray* parsed_selectors;
|
||||
#endif // #if KATANA_PARSER_DEBUG
|
||||
|
||||
KatanaSourcePosition* position;
|
||||
KatanaParserString default_namespace;
|
||||
|
||||
} KatanaParser;
|
||||
|
||||
|
||||
KatanaArray* katana_new_array(KatanaParser* parser);
|
||||
|
||||
|
||||
KatanaStylesheet* katana_new_stylesheet(KatanaParser* parser);
|
||||
void katana_parser_reset_declarations(KatanaParser* parser);
|
||||
|
||||
|
||||
void katana_add_namespace(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* uri);
|
||||
|
||||
|
||||
KatanaRule* katana_new_font_face(KatanaParser* parser);
|
||||
|
||||
|
||||
KatanaRule* katana_new_keyframes_rule(KatanaParser* parser, KatanaParserString* name, KatanaArray* keyframes, bool isPrefixed);
|
||||
KatanaKeyframe* katana_new_keyframe(KatanaParser* parser, KatanaArray* selectors);
|
||||
KatanaArray* katana_new_Keyframe_list(KatanaParser* parser);
|
||||
void katana_keyframe_rule_list_add(KatanaParser* parser, KatanaKeyframe* keyframe, KatanaArray* list);
|
||||
void katana_parser_clear_keyframes(KatanaParser* parser, KatanaArray* keyframes);
|
||||
|
||||
|
||||
void katana_set_charset(KatanaParser* parser, KatanaParserString* charset);
|
||||
|
||||
|
||||
KatanaRule* katana_new_import_rule(KatanaParser* parser, KatanaParserString* href, KatanaArray* media);
|
||||
|
||||
|
||||
KatanaValue* katana_new_value(KatanaParser* parser);
|
||||
KatanaValue* katana_new_dimension_value(KatanaParser* parser, KatanaParserNumber* value, KatanaValueUnit unit);
|
||||
KatanaValue* katana_new_number_value(KatanaParser* parser, int sign, KatanaParserNumber* value, KatanaValueUnit unit);
|
||||
KatanaValue* katana_new_operator_value(KatanaParser* parser, int value);
|
||||
KatanaValue* katana_new_ident_value(KatanaParser* parser, KatanaParserString* value);
|
||||
KatanaValue* katana_new_function_value(KatanaParser* parser, KatanaParserString* name, KatanaArray* args);
|
||||
KatanaValue* katana_new_list_value(KatanaParser* parser, KatanaArray* list);
|
||||
|
||||
void katana_value_set_string(KatanaParser* parser, KatanaValue* value, KatanaParserString* string);
|
||||
void katana_value_set_sign(KatanaParser* parser, KatanaValue* value, int sign);
|
||||
|
||||
|
||||
KatanaArray* katana_new_value_list(KatanaParser* parser);
|
||||
void katana_value_list_add(KatanaParser* parser, KatanaValue* value, KatanaArray* list);
|
||||
void katana_value_list_insert(KatanaParser* parser, KatanaValue* value, int index, KatanaArray* list);
|
||||
void katana_value_list_steal_values(KatanaParser* parser, KatanaArray* values, KatanaArray* list);
|
||||
|
||||
|
||||
KatanaRule* katana_new_media_rule(KatanaParser* parser, KatanaArray* medias, KatanaArray* rules);
|
||||
|
||||
|
||||
KatanaArray* katana_new_media_list(KatanaParser* parser);
|
||||
void katana_media_list_add(KatanaParser* parser, KatanaMediaQuery* media_query, KatanaArray* medias);
|
||||
|
||||
|
||||
KatanaMediaQuery* katana_new_media_query(KatanaParser* parser, KatanaMediaQueryRestrictor r, KatanaParserString *type, KatanaArray* exps);
|
||||
|
||||
|
||||
// i.e. (min-width: 960px)
|
||||
KatanaMediaQueryExp * katana_new_media_query_exp(KatanaParser* parser, KatanaParserString* feature, KatanaArray* values);
|
||||
|
||||
|
||||
KatanaArray* katana_new_media_query_exp_list(KatanaParser* parser);
|
||||
void katana_media_query_exp_list_add(KatanaParser* parser, KatanaMediaQueryExp* exp, KatanaArray* list);
|
||||
|
||||
|
||||
KatanaArray* katana_new_rule_list(KatanaParser* parser);
|
||||
KatanaArray* katana_rule_list_add(KatanaParser* parser, KatanaRule* rule, KatanaArray* rule_list);
|
||||
|
||||
|
||||
KatanaRule* katana_new_style_rule(KatanaParser* parser, KatanaArray* selectors);
|
||||
|
||||
|
||||
void katana_start_declaration(KatanaParser* parser);
|
||||
void katana_end_declaration(KatanaParser* parser, bool flag, bool ended);
|
||||
void katana_set_current_declaration(KatanaParser* parser, KatanaParserString* tag);
|
||||
bool katana_new_declaration(KatanaParser* parser, KatanaParserString* name, bool important, KatanaArray* values);
|
||||
void katana_parser_clear_declarations(KatanaParser* parser);
|
||||
|
||||
|
||||
void katana_start_selector(KatanaParser* parser);
|
||||
void katana_end_selector(KatanaParser* parser);
|
||||
|
||||
KatanaQualifiedName * katana_new_qualified_name(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* localName, KatanaParserString* uri);
|
||||
|
||||
KatanaSelector* katana_new_selector(KatanaParser* parser);
|
||||
KatanaSelector* katana_sink_floating_selector(KatanaParser* parser, KatanaSelector* selector);
|
||||
KatanaSelector* katana_rewrite_specifier_with_element_name(KatanaParser* parser, KatanaParserString* tag, KatanaSelector* specifier);
|
||||
KatanaSelector* katana_rewrite_specifier_with_namespace_if_needed(KatanaParser* parser, KatanaSelector* specifier);
|
||||
KatanaSelector* katana_rewrite_specifiers(KatanaParser* parser, KatanaSelector* specifiers, KatanaSelector* newSpecifier);
|
||||
|
||||
void katana_adopt_selector_list(KatanaParser* parser, KatanaArray* selectors, KatanaSelector* selector);
|
||||
void katana_selector_append(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation relation);
|
||||
void katana_selector_insert(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation before, KatanaSelectorRelation after);
|
||||
void katana_selector_prepend_with_element_name(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* tag);
|
||||
|
||||
KatanaArray* katana_new_selector_list(KatanaParser* parser);
|
||||
KatanaArray* katana_reusable_selector_list(KatanaParser* parser);
|
||||
void katana_selector_list_shink(KatanaParser* parser, int capacity, KatanaArray* list);
|
||||
void katana_selector_list_add(KatanaParser* parser, KatanaSelector* selector, KatanaArray* list);
|
||||
|
||||
void katana_selector_set_value(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* value);
|
||||
void katana_selector_set_argument(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* argument);
|
||||
void katana_selector_set_argument_with_number(KatanaParser* parser, KatanaSelector* selector, int sign, KatanaParserNumber* value);
|
||||
|
||||
bool katana_parse_attribute_match_type(KatanaParser* parser, KatanaAttributeMatchType, KatanaParserString* attr);
|
||||
|
||||
bool katana_selector_is_simple(KatanaParser* parser, KatanaSelector* selector);
|
||||
void katana_selector_extract_pseudo_type(KatanaSelector* selector);
|
||||
|
||||
|
||||
void katana_add_rule(KatanaParser* parser, KatanaRule* rule);
|
||||
|
||||
void katana_start_rule(KatanaParser* parser);
|
||||
void katana_end_rule(KatanaParser* parser, bool ended);
|
||||
|
||||
void katana_start_rule_header(KatanaParser* parser, KatanaRuleType type);
|
||||
void katana_end_rule_header(KatanaParser* parser);
|
||||
void katana_end_invalid_rule_header(KatanaParser* parser);
|
||||
void katana_start_rule_body(KatanaParser* parser);
|
||||
|
||||
|
||||
bool katana_string_is_function(KatanaParserString* string);
|
||||
void katana_string_clear(KatanaParser* parser, KatanaParserString* string);
|
||||
|
||||
|
||||
void katana_parse_internal_rule(KatanaParser* parser, KatanaRule* e);
|
||||
void katana_parse_internal_keyframe_rule(KatanaParser* parser, KatanaKeyframe* e);
|
||||
void katana_parse_internal_keyframe_key_list(KatanaParser* parser, KatanaArray* e);
|
||||
void katana_parse_internal_value(KatanaParser* parser, KatanaArray* e);
|
||||
void katana_parse_internal_media_list(KatanaParser* parser, KatanaArray* e);
|
||||
void katana_parse_internal_declaration_list(KatanaParser* parser, bool e);
|
||||
void katana_parse_internal_selector(KatanaParser* parser, KatanaArray* e);
|
||||
|
||||
|
||||
// Bison error
|
||||
void katanaerror(KATANALTYPE* yyloc, void* scanner, KatanaParser * parser, char*);
|
||||
|
||||
// Bison parser location
|
||||
KatanaSourcePosition* katana_parser_current_location(KatanaParser* parser, KATANALTYPE* yylloc);
|
||||
|
||||
// Log
|
||||
void katana_parser_log(KatanaParser* parser, const char * format, ...);
|
||||
|
||||
// Error
|
||||
void katana_parser_resume_error_logging();
|
||||
void katana_parser_report_error(KatanaParser* parser, KatanaSourcePosition* pos, const char *, ...);
|
||||
|
||||
// print
|
||||
void katana_print(const char * format, ...);
|
||||
|
||||
void katana_print_stylesheet(KatanaParser* parser, KatanaStylesheet* sheet);
|
||||
void katana_print_rule(KatanaParser* parser, KatanaRule* rule);
|
||||
void katana_print_font_face_rule(KatanaParser* parser, KatanaFontFaceRule* rule);
|
||||
void katana_print_import_rule(KatanaParser* parser, KatanaImportRule* rule);
|
||||
|
||||
void katana_print_media_query_exp(KatanaParser* parser, KatanaMediaQueryExp* exp);
|
||||
void katana_print_media_query(KatanaParser* parser, KatanaMediaQuery* query);
|
||||
void katana_print_media_list(KatanaParser* parser, KatanaArray* medias);
|
||||
void katana_print_media_rule(KatanaParser* parser, KatanaMediaRule* rule);
|
||||
|
||||
void katana_print_keyframes_rule(KatanaParser* parser, KatanaKeyframesRule* rule);
|
||||
void katana_print_keyframe(KatanaParser* parser, KatanaKeyframe* keyframe);
|
||||
|
||||
void katana_print_style_rule(KatanaParser* parser, KatanaStyleRule* rule);
|
||||
void katana_print_selector(KatanaParser* parser, KatanaSelector* selector);
|
||||
void katana_print_selector_list(KatanaParser* parser, KatanaArray* selectors);
|
||||
void katana_print_declaration(KatanaParser* parser, KatanaDeclaration* decl);
|
||||
void katana_print_declaration_list(KatanaParser* parser, KatanaArray* declarations);
|
||||
void katana_print_value_list(KatanaParser* parser, KatanaArray* values);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(__Katana__parser__) */
|
||||
658
Nuake/src/Vendors/katana-parser/selector.c
Normal file
658
Nuake/src/Vendors/katana-parser/selector.c
Normal file
@@ -0,0 +1,658 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "selector.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#undef assert
|
||||
#define assert(x)
|
||||
|
||||
// Refs:
|
||||
// http://www.w3.org/TR/css3-selectors/
|
||||
//
|
||||
|
||||
static KatanaPseudoType name_to_pseudo_type(const char* name, bool hasArguments);
|
||||
|
||||
bool katana_selector_crosses_tree_scopes(const KatanaSelector* selector)
|
||||
{
|
||||
// TODO: To be supported
|
||||
return false;
|
||||
}
|
||||
|
||||
// bool katana_is_attribute_selector(const KatanaSelector* selector)
|
||||
// {
|
||||
// return selector->match == KatanaSelectorMatchAttributeExact
|
||||
// || selector->match == KatanaSelectorMatchAttributeSet
|
||||
// || selector->match == KatanaSelectorMatchAttributeList
|
||||
// || selector->match == KatanaSelectorMatchAttributeHyphen
|
||||
// || selector->match == KatanaSelectorMatchAttributeContain
|
||||
// || selector->match == KatanaSelectorMatchAttributeBegin
|
||||
// || selector->match == KatanaSelectorMatchAttributeEnd;
|
||||
// }
|
||||
|
||||
KatanaPseudoType katana_parse_pseudo_type(const char* name, bool hasArguments)
|
||||
{
|
||||
KatanaPseudoType pseudoType = name_to_pseudo_type(name, hasArguments);
|
||||
if (pseudoType != KatanaPseudoUnknown)
|
||||
return pseudoType;
|
||||
|
||||
if (katana_string_has_prefix(name, "-webkit-"))
|
||||
return KatanaPseudoWebKitCustomElement;
|
||||
|
||||
return KatanaPseudoUnknown;
|
||||
}
|
||||
|
||||
void katana_selector_extract_pseudo_type(KatanaSelector* selector)
|
||||
{
|
||||
if (selector->pseudo == KatanaPseudoNotParsed)
|
||||
selector->pseudo = KatanaPseudoUnknown;
|
||||
|
||||
if (selector->match != KatanaSelectorMatchPseudoClass && selector->match != KatanaSelectorMatchPseudoElement && selector->match != KatanaSelectorMatchPagePseudoClass)
|
||||
return;
|
||||
bool hasArguments = (NULL != selector->data->argument) || (NULL != selector->data->selectors);
|
||||
selector->pseudo = katana_parse_pseudo_type(selector->data->value, hasArguments);
|
||||
|
||||
bool element = false; // pseudo-element
|
||||
bool compat = false; // single colon compatbility mode
|
||||
bool isPagePseudoClass = false; // Page pseudo-class
|
||||
|
||||
switch (selector->pseudo) {
|
||||
case KatanaPseudoAfter:
|
||||
case KatanaPseudoBefore:
|
||||
case KatanaPseudoFirstLetter:
|
||||
case KatanaPseudoFirstLine:
|
||||
compat = true;
|
||||
case KatanaPseudoBackdrop:
|
||||
case KatanaPseudoCue:
|
||||
case KatanaPseudoResizer:
|
||||
case KatanaPseudoScrollbar:
|
||||
case KatanaPseudoScrollbarCorner:
|
||||
case KatanaPseudoScrollbarButton:
|
||||
case KatanaPseudoScrollbarThumb:
|
||||
case KatanaPseudoScrollbarTrack:
|
||||
case KatanaPseudoScrollbarTrackPiece:
|
||||
case KatanaPseudoSelection:
|
||||
case KatanaPseudoWebKitCustomElement:
|
||||
case KatanaPseudoContent:
|
||||
case KatanaPseudoShadow:
|
||||
element = true;
|
||||
break;
|
||||
case KatanaPseudoUnknown:
|
||||
case KatanaPseudoEmpty:
|
||||
case KatanaPseudoFirstChild:
|
||||
case KatanaPseudoFirstOfType:
|
||||
case KatanaPseudoLastChild:
|
||||
case KatanaPseudoLastOfType:
|
||||
case KatanaPseudoOnlyChild:
|
||||
case KatanaPseudoOnlyOfType:
|
||||
case KatanaPseudoNthChild:
|
||||
case KatanaPseudoNthOfType:
|
||||
case KatanaPseudoNthLastChild:
|
||||
case KatanaPseudoNthLastOfType:
|
||||
case KatanaPseudoLink:
|
||||
case KatanaPseudoVisited:
|
||||
case KatanaPseudoAny:
|
||||
case KatanaPseudoAnyLink:
|
||||
case KatanaPseudoAutofill:
|
||||
case KatanaPseudoHover:
|
||||
case KatanaPseudoDrag:
|
||||
case KatanaPseudoFocus:
|
||||
case KatanaPseudoActive:
|
||||
case KatanaPseudoChecked:
|
||||
case KatanaPseudoEnabled:
|
||||
case KatanaPseudoFullPageMedia:
|
||||
case KatanaPseudoDefault:
|
||||
case KatanaPseudoDisabled:
|
||||
case KatanaPseudoOptional:
|
||||
case KatanaPseudoRequired:
|
||||
case KatanaPseudoReadOnly:
|
||||
case KatanaPseudoReadWrite:
|
||||
case KatanaPseudoScope:
|
||||
case KatanaPseudoValid:
|
||||
case KatanaPseudoInvalid:
|
||||
case KatanaPseudoIndeterminate:
|
||||
case KatanaPseudoTarget:
|
||||
case KatanaPseudoLang:
|
||||
case KatanaPseudoNot:
|
||||
case KatanaPseudoRoot:
|
||||
case KatanaPseudoWindowInactive:
|
||||
case KatanaPseudoCornerPresent:
|
||||
case KatanaPseudoDecrement:
|
||||
case KatanaPseudoIncrement:
|
||||
case KatanaPseudoHorizontal:
|
||||
case KatanaPseudoVertical:
|
||||
case KatanaPseudoStart:
|
||||
case KatanaPseudoEnd:
|
||||
case KatanaPseudoDoubleButton:
|
||||
case KatanaPseudoSingleButton:
|
||||
case KatanaPseudoNoButton:
|
||||
case KatanaPseudoNotParsed:
|
||||
case KatanaPseudoFullScreen:
|
||||
case KatanaPseudoFullScreenDocument:
|
||||
case KatanaPseudoFullScreenAncestor:
|
||||
case KatanaPseudoInRange:
|
||||
case KatanaPseudoOutOfRange:
|
||||
case KatanaPseudoFutureCue:
|
||||
case KatanaPseudoPastCue:
|
||||
case KatanaPseudoHost:
|
||||
case KatanaPseudoHostContext:
|
||||
case KatanaPseudoUnresolved:
|
||||
case KatanaPseudoSpatialNavigationFocus:
|
||||
case KatanaPseudoListBox:
|
||||
break;
|
||||
case KatanaPseudoFirstPage:
|
||||
case KatanaPseudoLeftPage:
|
||||
case KatanaPseudoRightPage:
|
||||
isPagePseudoClass = true;
|
||||
break;
|
||||
}
|
||||
|
||||
bool matchPagePseudoClass = (selector->match == KatanaSelectorMatchPagePseudoClass);
|
||||
if (matchPagePseudoClass != isPagePseudoClass)
|
||||
selector->pseudo = KatanaPseudoUnknown;
|
||||
else if (selector->match == KatanaSelectorMatchPseudoClass && element) {
|
||||
if (!compat)
|
||||
selector->pseudo = KatanaPseudoUnknown;
|
||||
else
|
||||
selector->match = KatanaSelectorMatchPseudoElement;
|
||||
} else if (selector->match == KatanaSelectorMatchPseudoElement && !element)
|
||||
selector->pseudo = KatanaPseudoUnknown;
|
||||
}
|
||||
|
||||
bool katana_selector_matches_pseudo_element(KatanaSelector* selector)
|
||||
{
|
||||
if (selector->pseudo == KatanaPseudoUnknown)
|
||||
katana_selector_extract_pseudo_type(selector);
|
||||
return selector->match == KatanaSelectorMatchPseudoElement;
|
||||
}
|
||||
|
||||
bool katana_selector_is_custom_pseudo_element(KatanaSelector* selector)
|
||||
{
|
||||
return selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoWebKitCustomElement;
|
||||
}
|
||||
|
||||
bool katana_selector_is_direct_adjacent(KatanaSelector* selector)
|
||||
{
|
||||
return selector->relation == KatanaSelectorRelationDirectAdjacent || selector->relation == KatanaSelectorRelationIndirectAdjacent;
|
||||
}
|
||||
|
||||
bool katana_selector_is_adjacent(KatanaSelector* selector)
|
||||
{
|
||||
return selector->relation == KatanaSelectorRelationDirectAdjacent;
|
||||
}
|
||||
|
||||
bool katana_selector_is_shadow(KatanaSelector* selector)
|
||||
{
|
||||
return selector->relation == KatanaSelectorRelationShadowPseudo || selector->relation == KatanaSelectorRelationShadowDeep;
|
||||
}
|
||||
|
||||
bool katana_selector_is_sibling(KatanaSelector* selector)
|
||||
{
|
||||
katana_selector_extract_pseudo_type(selector);
|
||||
|
||||
KatanaPseudoType type = selector->pseudo;
|
||||
return selector->relation == KatanaSelectorRelationDirectAdjacent
|
||||
|| selector->relation == KatanaSelectorRelationIndirectAdjacent
|
||||
|| type == KatanaPseudoEmpty
|
||||
|| type == KatanaPseudoFirstChild
|
||||
|| type == KatanaPseudoFirstOfType
|
||||
|| type == KatanaPseudoLastChild
|
||||
|| type == KatanaPseudoLastOfType
|
||||
|| type == KatanaPseudoOnlyChild
|
||||
|| type == KatanaPseudoOnlyOfType
|
||||
|| type == KatanaPseudoNthChild
|
||||
|| type == KatanaPseudoNthOfType
|
||||
|| type == KatanaPseudoNthLastChild
|
||||
|| type == KatanaPseudoNthLastOfType;
|
||||
}
|
||||
|
||||
bool katana_selector_is_attribute(const KatanaSelector* selector)
|
||||
{
|
||||
return selector->match >= KatanaSelectorMatchFirstAttribute;
|
||||
}
|
||||
|
||||
bool katana_selector_is_content_pseudo_element(KatanaSelector* selector)
|
||||
{
|
||||
katana_selector_extract_pseudo_type(selector);
|
||||
return selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoContent;
|
||||
}
|
||||
|
||||
bool katana_selector_is_shadow_pseudo_element(KatanaSelector* selector)
|
||||
{
|
||||
return selector->match == KatanaSelectorMatchPseudoElement
|
||||
&& selector->pseudo == KatanaPseudoShadow;
|
||||
}
|
||||
|
||||
bool katana_selector_is_host_pseudo_class(KatanaSelector* selector)
|
||||
{
|
||||
return selector->match == KatanaSelectorMatchPseudoClass && (selector->pseudo == KatanaPseudoHost || selector->pseudo == KatanaPseudoHostContext);
|
||||
}
|
||||
|
||||
bool katana_selector_is_tree_boundary_crossing(KatanaSelector* selector)
|
||||
{
|
||||
katana_selector_extract_pseudo_type(selector);
|
||||
return selector->match == KatanaSelectorMatchPseudoClass && (selector->pseudo == KatanaPseudoHost || selector->pseudo == KatanaPseudoHostContext);
|
||||
}
|
||||
|
||||
bool katana_selector_is_insertion_point_crossing(KatanaSelector* selector)
|
||||
{
|
||||
katana_selector_extract_pseudo_type(selector);
|
||||
return (selector->match == KatanaSelectorMatchPseudoClass && selector->pseudo == KatanaPseudoHostContext)
|
||||
|| (selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoContent);
|
||||
}
|
||||
|
||||
KatanaParserString* katana_build_relation_selector_string(KatanaParser* parser, const char* relation, KatanaParserString* string, KatanaParserString* next, KatanaSelector* tagHistory)
|
||||
{
|
||||
if ( NULL != relation ) {
|
||||
katana_string_prepend_characters(parser, relation, string);
|
||||
}
|
||||
|
||||
if ( NULL != next ) {
|
||||
katana_string_append_string(parser, next, string);
|
||||
}
|
||||
|
||||
KatanaParserString * result = katana_selector_to_string(parser, tagHistory, (KatanaParserString*)string);
|
||||
katana_parser_deallocate(parser, (void*) string->data);
|
||||
katana_parser_deallocate(parser, (void*) string);
|
||||
return result;
|
||||
}
|
||||
|
||||
KatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next)
|
||||
{
|
||||
KatanaParserString* string = katana_parser_allocate(parser, sizeof(KatanaParserString));
|
||||
katana_string_init(parser, string);
|
||||
|
||||
bool tag_is_implicit = true;
|
||||
|
||||
if (selector->match == KatanaSelectorMatchTag && tag_is_implicit)
|
||||
{
|
||||
if ( NULL == selector->tag->prefix )
|
||||
katana_string_append_characters(parser, selector->tag->local, string);
|
||||
else {
|
||||
katana_string_append_characters(parser, selector->tag->prefix, string);
|
||||
katana_string_append_characters(parser, "|", string);
|
||||
katana_string_append_characters(parser, selector->tag->local, string);
|
||||
}
|
||||
}
|
||||
|
||||
const KatanaSelector* cs = selector;
|
||||
|
||||
while (true) {
|
||||
if (cs->match == KatanaSelectorMatchId) {
|
||||
katana_string_append_characters(parser, "#", string);
|
||||
katana_string_append_characters(parser, cs->data->value, string);
|
||||
} else if (cs->match == KatanaSelectorMatchClass) {
|
||||
katana_string_append_characters(parser, ".", string);
|
||||
katana_string_append_characters(parser, cs->data->value, string);
|
||||
} else if (cs->match == KatanaSelectorMatchPseudoClass || cs->match == KatanaSelectorMatchPagePseudoClass) {
|
||||
katana_string_append_characters(parser, ":", string);
|
||||
katana_string_append_characters(parser, cs->data->value, string);
|
||||
|
||||
switch (cs->pseudo) {
|
||||
case KatanaPseudoAny:
|
||||
case KatanaPseudoNot:
|
||||
case KatanaPseudoHost:
|
||||
case KatanaPseudoHostContext: {
|
||||
if ( cs->data->selectors ) {
|
||||
KatanaArray* sels = cs->data->selectors;
|
||||
for (size_t i=0; i<sels->length; i++) {
|
||||
KatanaParserString* str = katana_selector_to_string(parser, sels->data[i], NULL);
|
||||
katana_string_append_string(parser, str, string);
|
||||
katana_parser_deallocate(parser, (void*) str->data);
|
||||
katana_parser_deallocate(parser, (void*) str);
|
||||
if ( i != sels->length -1 ) {
|
||||
katana_string_append_characters(parser, ", ", string);
|
||||
}
|
||||
}
|
||||
katana_string_append_characters(parser, ")", string);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KatanaPseudoLang:
|
||||
case KatanaPseudoNthChild:
|
||||
case KatanaPseudoNthLastChild:
|
||||
case KatanaPseudoNthOfType:
|
||||
case KatanaPseudoNthLastOfType: {
|
||||
katana_string_append_characters(parser, cs->data->argument, string);
|
||||
katana_string_append_characters(parser, ")", string);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (cs->match == KatanaSelectorMatchPseudoElement) {
|
||||
katana_string_append_characters(parser, "::", string);
|
||||
katana_string_append_characters(parser, cs->data->value, string);
|
||||
} else if (katana_selector_is_attribute(cs)) {
|
||||
katana_string_append_characters(parser, "[", string);
|
||||
if (NULL != cs->data->attribute->prefix) {
|
||||
katana_string_append_characters(parser, cs->data->attribute->prefix, string);
|
||||
katana_string_append_characters(parser, "|", string);
|
||||
}
|
||||
katana_string_append_characters(parser, cs->data->attribute->local, string);
|
||||
switch (cs->match) {
|
||||
case KatanaSelectorMatchAttributeExact:
|
||||
katana_string_append_characters(parser, "=", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeSet:
|
||||
katana_string_append_characters(parser, "]", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeList:
|
||||
katana_string_append_characters(parser, "~=", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeHyphen:
|
||||
katana_string_append_characters(parser, "|=", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeBegin:
|
||||
katana_string_append_characters(parser, "^=", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeEnd:
|
||||
katana_string_append_characters(parser, "$=", string);
|
||||
break;
|
||||
case KatanaSelectorMatchAttributeContain:
|
||||
katana_string_append_characters(parser, "*=", string);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (cs->match != KatanaSelectorMatchAttributeSet) {
|
||||
katana_string_append_characters(parser, "\"", string);
|
||||
katana_string_append_characters(parser, cs->data->value, string);
|
||||
katana_string_append_characters(parser, "\"", string);
|
||||
if (cs->data->bits.attributeMatchType == KatanaAttributeMatchTypeCaseInsensitive)
|
||||
katana_string_append_characters(parser, " i", string);
|
||||
katana_string_append_characters(parser, "]", string);
|
||||
}
|
||||
}
|
||||
if (cs->relation != KatanaSelectorRelationSubSelector || !cs->tagHistory)
|
||||
break;
|
||||
cs = cs->tagHistory;
|
||||
}
|
||||
|
||||
KatanaSelector* tagHistory = cs->tagHistory;
|
||||
|
||||
if ( NULL != tagHistory ) {
|
||||
switch (cs->relation) {
|
||||
case KatanaSelectorRelationDescendant:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, " ", string, next, tagHistory);
|
||||
}
|
||||
case KatanaSelectorRelationChild:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, " > ", string, next, tagHistory);
|
||||
}
|
||||
case KatanaSelectorRelationShadowDeep:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, " /deep/ ", string, next, tagHistory);
|
||||
}
|
||||
case KatanaSelectorRelationDirectAdjacent:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, " + ", string, next, tagHistory);
|
||||
}
|
||||
case KatanaSelectorRelationIndirectAdjacent:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, " ~ ", string, next, tagHistory);
|
||||
}
|
||||
case KatanaSelectorRelationSubSelector:
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
case KatanaSelectorRelationShadowPseudo:
|
||||
{
|
||||
return katana_build_relation_selector_string(parser, NULL, string, next, tagHistory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( NULL != next ) {
|
||||
katana_string_append_string(parser, (KatanaParserString*)next, string);
|
||||
}
|
||||
|
||||
return (KatanaParserString*)string;
|
||||
}
|
||||
|
||||
unsigned calc_specificity_for_one_selector(const KatanaSelector* selector)
|
||||
{
|
||||
switch ( selector->match ) {
|
||||
case KatanaSelectorMatchId:
|
||||
return 0x10000;
|
||||
|
||||
case KatanaSelectorMatchPseudoClass:
|
||||
case KatanaSelectorMatchAttributeExact:
|
||||
case KatanaSelectorMatchClass:
|
||||
case KatanaSelectorMatchAttributeSet:
|
||||
case KatanaSelectorMatchAttributeList:
|
||||
case KatanaSelectorMatchAttributeHyphen:
|
||||
case KatanaSelectorMatchPseudoElement:
|
||||
case KatanaSelectorMatchAttributeContain:
|
||||
case KatanaSelectorMatchAttributeBegin:
|
||||
case KatanaSelectorMatchAttributeEnd:
|
||||
return 0x100;
|
||||
|
||||
case KatanaSelectorMatchTag:
|
||||
return !stricmp(selector->tag->local, "*") ? 0 : 1;
|
||||
case KatanaSelectorMatchUnknown:
|
||||
case KatanaSelectorMatchPagePseudoClass:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned katana_calc_specificity_for_selector(KatanaSelector* selector)
|
||||
{
|
||||
if ( NULL == selector ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned idMask = 0xff0000;
|
||||
static const unsigned classMask = 0xff00;
|
||||
static const unsigned elementMask = 0xff;
|
||||
|
||||
unsigned total = 0;
|
||||
unsigned temp = 0;
|
||||
|
||||
for (const KatanaSelector * next = selector; next; next = next->tagHistory)
|
||||
{
|
||||
temp = total + calc_specificity_for_one_selector(next);
|
||||
|
||||
if ((temp & idMask) < (total & idMask))
|
||||
total |= idMask;
|
||||
else if ((temp & classMask) < (total & classMask))
|
||||
total |= classMask;
|
||||
else if ((temp & elementMask) < (total & elementMask))
|
||||
total |= elementMask;
|
||||
else
|
||||
total = temp;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
// Could be made smaller and faster by replacing pointer with an
|
||||
// offset into a string buffer and making the bit fields smaller but
|
||||
// that could not be maintained by hand.
|
||||
typedef struct {
|
||||
const char* string;
|
||||
unsigned type:8;
|
||||
} KatanaNameToPseudoStruct;
|
||||
|
||||
// These tables should be kept sorted.
|
||||
const static KatanaNameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
|
||||
{"-internal-list-box", KatanaPseudoListBox},
|
||||
{"-internal-media-controls-cast-button", KatanaPseudoWebKitCustomElement},
|
||||
{"-internal-media-controls-overlay-cast-button", KatanaPseudoWebKitCustomElement},
|
||||
{"-internal-spatial-navigation-focus", KatanaPseudoSpatialNavigationFocus},
|
||||
{"-webkit-any-link", KatanaPseudoAnyLink},
|
||||
{"-webkit-autofill", KatanaPseudoAutofill},
|
||||
{"-webkit-drag", KatanaPseudoDrag},
|
||||
{"-webkit-full-page-media", KatanaPseudoFullPageMedia},
|
||||
{"-webkit-full-screen", KatanaPseudoFullScreen},
|
||||
{"-webkit-full-screen-ancestor", KatanaPseudoFullScreenAncestor},
|
||||
{"-webkit-full-screen-document", KatanaPseudoFullScreenDocument},
|
||||
{"-webkit-resizer", KatanaPseudoResizer},
|
||||
{"-webkit-scrollbar", KatanaPseudoScrollbar},
|
||||
{"-webkit-scrollbar-button", KatanaPseudoScrollbarButton},
|
||||
{"-webkit-scrollbar-corner", KatanaPseudoScrollbarCorner},
|
||||
{"-webkit-scrollbar-thumb", KatanaPseudoScrollbarThumb},
|
||||
{"-webkit-scrollbar-track", KatanaPseudoScrollbarTrack},
|
||||
{"-webkit-scrollbar-track-piece", KatanaPseudoScrollbarTrackPiece},
|
||||
{"active", KatanaPseudoActive},
|
||||
{"after", KatanaPseudoAfter},
|
||||
{"backdrop", KatanaPseudoBackdrop},
|
||||
{"before", KatanaPseudoBefore},
|
||||
{"checked", KatanaPseudoChecked},
|
||||
{"content", KatanaPseudoContent},
|
||||
{"corner-present", KatanaPseudoCornerPresent},
|
||||
{"cue", KatanaPseudoWebKitCustomElement},
|
||||
{"decrement", KatanaPseudoDecrement},
|
||||
{"default", KatanaPseudoDefault},
|
||||
{"disabled", KatanaPseudoDisabled},
|
||||
{"double-button", KatanaPseudoDoubleButton},
|
||||
{"empty", KatanaPseudoEmpty},
|
||||
{"enabled", KatanaPseudoEnabled},
|
||||
{"end", KatanaPseudoEnd},
|
||||
{"first", KatanaPseudoFirstPage},
|
||||
{"first-child", KatanaPseudoFirstChild},
|
||||
{"first-letter", KatanaPseudoFirstLetter},
|
||||
{"first-line", KatanaPseudoFirstLine},
|
||||
{"first-of-type", KatanaPseudoFirstOfType},
|
||||
{"focus", KatanaPseudoFocus},
|
||||
{"future", KatanaPseudoFutureCue},
|
||||
{"horizontal", KatanaPseudoHorizontal},
|
||||
{"host", KatanaPseudoHost},
|
||||
{"hover", KatanaPseudoHover},
|
||||
{"in-range", KatanaPseudoInRange},
|
||||
{"increment", KatanaPseudoIncrement},
|
||||
{"indeterminate", KatanaPseudoIndeterminate},
|
||||
{"invalid", KatanaPseudoInvalid},
|
||||
{"last-child", KatanaPseudoLastChild},
|
||||
{"last-of-type", KatanaPseudoLastOfType},
|
||||
{"left", KatanaPseudoLeftPage},
|
||||
{"link", KatanaPseudoLink},
|
||||
{"no-button", KatanaPseudoNoButton},
|
||||
{"only-child", KatanaPseudoOnlyChild},
|
||||
{"only-of-type", KatanaPseudoOnlyOfType},
|
||||
{"optional", KatanaPseudoOptional},
|
||||
{"out-of-range", KatanaPseudoOutOfRange},
|
||||
{"past", KatanaPseudoPastCue},
|
||||
{"read-only", KatanaPseudoReadOnly},
|
||||
{"read-write", KatanaPseudoReadWrite},
|
||||
{"required", KatanaPseudoRequired},
|
||||
{"right", KatanaPseudoRightPage},
|
||||
{"root", KatanaPseudoRoot},
|
||||
{"scope", KatanaPseudoScope},
|
||||
{"selection", KatanaPseudoSelection},
|
||||
{"shadow", KatanaPseudoShadow},
|
||||
{"single-button", KatanaPseudoSingleButton},
|
||||
{"start", KatanaPseudoStart},
|
||||
{"target", KatanaPseudoTarget},
|
||||
{"unresolved", KatanaPseudoUnresolved},
|
||||
{"valid", KatanaPseudoValid},
|
||||
{"vertical", KatanaPseudoVertical},
|
||||
{"visited", KatanaPseudoVisited},
|
||||
{"window-inactive", KatanaPseudoWindowInactive},
|
||||
};
|
||||
|
||||
const static KatanaNameToPseudoStruct kPseudoTypeWithArgumentsMap[] = {
|
||||
{"-webkit-any(", KatanaPseudoAny},
|
||||
{"cue(", KatanaPseudoCue},
|
||||
{"host(", KatanaPseudoHost},
|
||||
{"host-context(", KatanaPseudoHostContext},
|
||||
{"lang(", KatanaPseudoLang},
|
||||
{"not(", KatanaPseudoNot},
|
||||
{"nth-child(", KatanaPseudoNthChild},
|
||||
{"nth-last-child(", KatanaPseudoNthLastChild},
|
||||
{"nth-last-of-type(", KatanaPseudoNthLastOfType},
|
||||
{"nth-of-type(", KatanaPseudoNthOfType},
|
||||
};
|
||||
|
||||
static const KatanaNameToPseudoStruct* lower_bound(const KatanaNameToPseudoStruct *map,
|
||||
size_t count, const char* key);
|
||||
|
||||
static KatanaPseudoType name_to_pseudo_type(const char* name, bool hasArguments)
|
||||
{
|
||||
if (NULL == name)
|
||||
return KatanaPseudoUnknown;
|
||||
|
||||
const KatanaNameToPseudoStruct* pseudoTypeMap;
|
||||
size_t count;
|
||||
|
||||
if (hasArguments) {
|
||||
pseudoTypeMap = kPseudoTypeWithArgumentsMap;
|
||||
count = sizeof(kPseudoTypeWithArgumentsMap) / sizeof(KatanaNameToPseudoStruct);
|
||||
} else {
|
||||
pseudoTypeMap = kPseudoTypeWithoutArgumentsMap;
|
||||
count = sizeof(kPseudoTypeWithoutArgumentsMap) / sizeof(KatanaNameToPseudoStruct);
|
||||
}
|
||||
|
||||
const KatanaNameToPseudoStruct* match = lower_bound(pseudoTypeMap, count, name);
|
||||
if ( match == (pseudoTypeMap + count)
|
||||
|| 0 != stricmp(match->string, name) )
|
||||
return KatanaPseudoUnknown;
|
||||
|
||||
return match->type;
|
||||
}
|
||||
|
||||
static const KatanaNameToPseudoStruct* lower_bound(const KatanaNameToPseudoStruct *array,
|
||||
size_t size, const char* key) {
|
||||
const KatanaNameToPseudoStruct* it;
|
||||
const KatanaNameToPseudoStruct* first = array;
|
||||
size_t count = size, step;
|
||||
while (count > 0) {
|
||||
it = first;
|
||||
step = count / 2;
|
||||
it += step;
|
||||
if (strncmp(it->string, key, strlen(key)) < 0) {
|
||||
first = ++it;
|
||||
count -= step + 1;
|
||||
} else count = step;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
#if KATANA_PARSER_DEBUG
|
||||
|
||||
void test_lower_bound()
|
||||
{
|
||||
const KatanaNameToPseudoStruct* pseudoTypeMap;
|
||||
size_t count;
|
||||
|
||||
pseudoTypeMap = kPseudoTypeWithArgumentsMap;
|
||||
count = sizeof(kPseudoTypeWithArgumentsMap) / sizeof(KatanaNameToPseudoStruct);
|
||||
|
||||
for ( size_t i = 0; i < count; i++ ) {
|
||||
const KatanaNameToPseudoStruct* res = lower_bound(pseudoTypeMap, count, pseudoTypeMap[i].string);
|
||||
assert(pseudoTypeMap[i].type == res->type);
|
||||
}
|
||||
|
||||
pseudoTypeMap = kPseudoTypeWithoutArgumentsMap;
|
||||
count = sizeof(kPseudoTypeWithoutArgumentsMap) / sizeof(KatanaNameToPseudoStruct);
|
||||
|
||||
for ( size_t i = 0; i < count; i++ ) {
|
||||
const KatanaNameToPseudoStruct* res = lower_bound(pseudoTypeMap, count, pseudoTypeMap[i].string);
|
||||
assert(pseudoTypeMap[i].type == res->type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if KATANA_PARSER_DEBUG
|
||||
54
Nuake/src/Vendors/katana-parser/selector.h
Normal file
54
Nuake/src/Vendors/katana-parser/selector.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __Katana__selector__
|
||||
#define __Katana__selector__
|
||||
|
||||
#include <stdio.h>
|
||||
#include "katana.h"
|
||||
#include "parser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
KatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next);
|
||||
|
||||
bool katana_selector_crosses_tree_scopes(const KatanaSelector* selector);
|
||||
bool katana_selector_matches_pseudo_element(KatanaSelector* selector);
|
||||
bool katana_selector_is_custom_pseudo_element(KatanaSelector* selector);
|
||||
bool katana_selector_is_direct_adjacent(KatanaSelector* selector);
|
||||
bool katana_selector_is_adjacent(KatanaSelector* selector);
|
||||
bool katana_selector_is_shadow(KatanaSelector* selector);
|
||||
bool katana_selector_is_sibling(KatanaSelector* selector);
|
||||
bool katana_selector_is_attribute(const KatanaSelector* selector);
|
||||
bool katana_selector_is_content_pseudo_element(KatanaSelector* selector);
|
||||
bool katana_selector_is_shadow_pseudo_element(KatanaSelector* selector);
|
||||
bool katana_selector_is_host_pseudo_class(KatanaSelector* selector);
|
||||
bool katana_selector_is_tree_boundary_crossing(KatanaSelector* selector);
|
||||
bool katana_selector_is_insertion_point_crossing(KatanaSelector* selector);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(__Katana__selector__) */
|
||||
304
Nuake/src/Vendors/katana-parser/tokenizer.c
Normal file
304
Nuake/src/Vendors/katana-parser/tokenizer.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "tokenizer.h"
|
||||
#include "katana.tab.h"
|
||||
#include "katana.lex.h"
|
||||
#include "parser.h"
|
||||
#include "foundation.h"
|
||||
|
||||
#undef assert
|
||||
#define assert(x)
|
||||
|
||||
static inline double katana_characters_to_double(const char* data, size_t length, bool* ok);
|
||||
static inline bool katana_is_html_space(char c);
|
||||
static inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok);
|
||||
|
||||
#ifdef KATANA_FELX_DEBUG
|
||||
#if KATANA_FELX_DEBUG
|
||||
static char * katana_token_string(int tok);
|
||||
#endif // #if KATANA_FELX_DEBUG
|
||||
#endif // #ifdef KATANA_FELX_DEBUG
|
||||
|
||||
/**
|
||||
* A hook function of flex, processing tokens which will be passed to bison
|
||||
*
|
||||
* @param yylval the medium for flex and bison
|
||||
* @param yyscanner flex state
|
||||
* @param tok the type of token
|
||||
*
|
||||
* @return the type of token
|
||||
*/
|
||||
int katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok)
|
||||
{
|
||||
char* origin_text = katanaget_text(scanner);
|
||||
|
||||
yy_size_t len = 0;
|
||||
|
||||
char* text = katana_normalize_text(&len, origin_text, katanaget_leng(scanner), tok);
|
||||
|
||||
#ifdef KATANA_FELX_DEBUG
|
||||
#if KATANA_FELX_DEBUG
|
||||
if ( tok == KATANA_CSS_WHITESPACE ) {
|
||||
katana_parser_log(parser, "【%30s】=>【%30s】: %s", "", "", katana_token_string(tok));
|
||||
} else {
|
||||
katana_parser_log(parser, "【%30s】=>【%30s】: %s", origin_text, text, katana_token_string(tok));
|
||||
}
|
||||
#endif // #if KATANA_FELX_DEBUG
|
||||
#endif // #ifdef KATANA_FELX_DEBUG
|
||||
yy_size_t length = len;
|
||||
switch ( tok ) {
|
||||
case KATANA_CSS_INCLUDES:
|
||||
case KATANA_CSS_DASHMATCH:
|
||||
case KATANA_CSS_BEGINSWITH:
|
||||
case KATANA_CSS_ENDSWITH:
|
||||
case KATANA_CSS_CONTAINS:
|
||||
break;
|
||||
case KATANA_CSS_STRING:
|
||||
case KATANA_CSS_IDENT:
|
||||
case KATANA_CSS_NTH:
|
||||
|
||||
case KATANA_CSS_HEX:
|
||||
case KATANA_CSS_IDSEL:
|
||||
|
||||
case KATANA_CSS_DIMEN:
|
||||
case KATANA_CSS_INVALIDDIMEN:
|
||||
case KATANA_CSS_URI:
|
||||
case KATANA_CSS_FUNCTION:
|
||||
case KATANA_CSS_ANYFUNCTION:
|
||||
case KATANA_CSS_CUEFUNCTION:
|
||||
case KATANA_CSS_NOTFUNCTION:
|
||||
case KATANA_CSS_CALCFUNCTION:
|
||||
case KATANA_CSS_MINFUNCTION:
|
||||
case KATANA_CSS_MAXFUNCTION:
|
||||
case KATANA_CSS_HOSTFUNCTION:
|
||||
case KATANA_CSS_HOSTCONTEXTFUNCTION:
|
||||
case KATANA_CSS_UNICODERANGE:
|
||||
{
|
||||
lval->string.data = text;
|
||||
lval->string.length = length;
|
||||
}
|
||||
break;
|
||||
|
||||
case KATANA_CSS_IMPORT_SYM:
|
||||
case KATANA_CSS_PAGE_SYM:
|
||||
case KATANA_CSS_MEDIA_SYM:
|
||||
case KATANA_CSS_SUPPORTS_SYM:
|
||||
case KATANA_CSS_FONT_FACE_SYM:
|
||||
case KATANA_CSS_CHARSET_SYM:
|
||||
case KATANA_CSS_NAMESPACE_SYM:
|
||||
// case KATANA_CSS_VIEWPORT_RULE_SYM:
|
||||
case KATANA_INTERNAL_DECLS_SYM:
|
||||
case KATANA_INTERNAL_MEDIALIST_SYM:
|
||||
case KATANA_INTERNAL_RULE_SYM:
|
||||
case KATANA_INTERNAL_SELECTOR_SYM:
|
||||
case KATANA_INTERNAL_VALUE_SYM:
|
||||
case KATANA_INTERNAL_KEYFRAME_RULE_SYM:
|
||||
case KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM:
|
||||
case KATANA_INTERNAL_SUPPORTS_CONDITION_SYM:
|
||||
case KATANA_CSS_KEYFRAMES_SYM:
|
||||
break;
|
||||
case KATANA_CSS_QEMS:
|
||||
length--;
|
||||
case KATANA_CSS_GRADS:
|
||||
case KATANA_CSS_TURNS:
|
||||
length--;
|
||||
case KATANA_CSS_DEGS:
|
||||
case KATANA_CSS_RADS:
|
||||
case KATANA_CSS_KHERTZ:
|
||||
case KATANA_CSS_REMS:
|
||||
length--;
|
||||
case KATANA_CSS_MSECS:
|
||||
case KATANA_CSS_HERTZ:
|
||||
case KATANA_CSS_EMS:
|
||||
case KATANA_CSS_EXS:
|
||||
case KATANA_CSS_PXS:
|
||||
case KATANA_CSS_CMS:
|
||||
case KATANA_CSS_MMS:
|
||||
case KATANA_CSS_INS:
|
||||
case KATANA_CSS_PTS:
|
||||
case KATANA_CSS_PCS:
|
||||
length--;
|
||||
case KATANA_CSS_SECS:
|
||||
case KATANA_CSS_PERCENTAGE:
|
||||
length--;
|
||||
case KATANA_CSS_FLOATTOKEN:
|
||||
lval->number.val = katana_characters_to_double(text, length, NULL);
|
||||
lval->number.raw.data = text;
|
||||
lval->number.raw.length = len;
|
||||
break;
|
||||
case KATANA_CSS_INTEGER:
|
||||
lval->number.val = (int)katana_characters_to_double(text, length, NULL);
|
||||
lval->number.raw.data = text;
|
||||
lval->number.raw.length = len;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format token
|
||||
*
|
||||
* @param length
|
||||
* @param origin_text original text from the flex
|
||||
* @param origin_length formatted length
|
||||
* @param tok
|
||||
*
|
||||
* @return normalized text
|
||||
*/
|
||||
static inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok)
|
||||
{
|
||||
char * start = origin_text;
|
||||
yy_size_t l = origin_length;
|
||||
switch ( tok ) {
|
||||
case KATANA_CSS_STRING:
|
||||
l--;
|
||||
/* nobreak */
|
||||
case KATANA_CSS_HEX:
|
||||
case KATANA_CSS_IDSEL:
|
||||
start++;
|
||||
l--;
|
||||
break;
|
||||
case KATANA_CSS_URI:
|
||||
// "url("{w}{string}{w}")"
|
||||
// "url("{w}{url}{w}")"
|
||||
// strip "url(" and ")"
|
||||
start += 4;
|
||||
l -= 5;
|
||||
// strip {w}
|
||||
while (l && katana_is_html_space(*start)) {
|
||||
++start;
|
||||
--l;
|
||||
}
|
||||
while (l && katana_is_html_space(start[l - 1]))
|
||||
--l;
|
||||
if (l && (*start == '"' || *start == '\'')) {
|
||||
assert(l >= 2 && start[l - 1] == *start);
|
||||
++start;
|
||||
l -= 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*length = l;
|
||||
return start;
|
||||
}
|
||||
|
||||
double katana_characters_to_double(const char* data, size_t length, bool* ok)
|
||||
{
|
||||
if (!length) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
char* bytes = malloc(sizeof(char) * (length + 1));
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
bytes[i] = data[i] < 0x7F ? data[i] : '?';
|
||||
bytes[length] = '\0';
|
||||
char* end;
|
||||
double val = strtod(bytes, &end);
|
||||
if (ok)
|
||||
*ok = (end == 0 || *end == '\0');
|
||||
free(bytes);
|
||||
return val;
|
||||
}
|
||||
|
||||
#ifdef KATANA_FELX_DEBUG
|
||||
#if KATANA_FELX_DEBUG
|
||||
static char * katana_token_table[] = {
|
||||
"TOKEN_EOF", "LOWEST_PREC", "UNIMPORTANT_TOK",
|
||||
"KATANA_CSS_SGML_CD", "KATANA_CSS_WHITESPACE", "KATANA_CSS_INCLUDES",
|
||||
"KATANA_CSS_DASHMATCH", "KATANA_CSS_BEGINSWITH", "KATANA_CSS_ENDSWITH",
|
||||
"KATANA_CSS_CONTAINS", "KATANA_CSS_STRING", "KATANA_CSS_IDENT",
|
||||
"KATANA_CSS_NTH", "KATANA_CSS_HEX", "KATANA_CSS_IDSEL", "KATANA_CSS_IMPORT_SYM", "KATANA_CSS_PAGE_SYM",
|
||||
"KATANA_CSS_MEDIA_SYM", "KATANA_CSS_SUPPORTS_SYM",
|
||||
"KATANA_CSS_FONT_FACE_SYM", "KATANA_CSS_CHARSET_SYM",
|
||||
"KATANA_CSS_NAMESPACE_SYM", "KATANA_INTERNAL_DECLS_SYM",
|
||||
"KATANA_INTERNAL_MEDIALIST_SYM", "KATANA_INTERNAL_RULE_SYM",
|
||||
"KATANA_INTERNAL_SELECTOR_SYM", "KATANA_INTERNAL_VALUE_SYM",
|
||||
"KATANA_INTERNAL_KEYFRAME_RULE_SYM",
|
||||
"KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM",
|
||||
"KATANA_INTERNAL_SUPPORTS_CONDITION_SYM", "KATANA_CSS_KEYFRAMES_SYM",
|
||||
"KATANA_CSS_ATKEYWORD", "KATANA_CSS_IMPORTANT_SYM",
|
||||
"KATANA_CSS_MEDIA_NOT", "KATANA_CSS_MEDIA_ONLY", "KATANA_CSS_MEDIA_AND",
|
||||
"KATANA_CSS_MEDIA_OR", "KATANA_CSS_SUPPORTS_NOT",
|
||||
"KATANA_CSS_SUPPORTS_AND", "KATANA_CSS_SUPPORTS_OR", "KATANA_CSS_REMS",
|
||||
"KATANA_CSS_CHS", "KATANA_CSS_QEMS", "KATANA_CSS_EMS", "KATANA_CSS_EXS",
|
||||
"KATANA_CSS_PXS", "KATANA_CSS_CMS", "KATANA_CSS_MMS", "KATANA_CSS_INS",
|
||||
"KATANA_CSS_PTS", "KATANA_CSS_PCS", "KATANA_CSS_DEGS", "KATANA_CSS_RADS",
|
||||
"KATANA_CSS_GRADS", "KATANA_CSS_TURNS", "KATANA_CSS_MSECS",
|
||||
"KATANA_CSS_SECS", "KATANA_CSS_HERTZ", "KATANA_CSS_KHERTZ",
|
||||
"KATANA_CSS_DIMEN", "KATANA_CSS_INVALIDDIMEN", "KATANA_CSS_PERCENTAGE",
|
||||
"KATANA_CSS_FLOATTOKEN", "KATANA_CSS_INTEGER", "KATANA_CSS_VW",
|
||||
"KATANA_CSS_VH", "KATANA_CSS_VMIN", "KATANA_CSS_VMAX", "KATANA_CSS_DPPX",
|
||||
"KATANA_CSS_DPI", "KATANA_CSS_DPCM", "KATANA_CSS_FR", "KATANA_CSS_URI",
|
||||
"KATANA_CSS_FUNCTION", "KATANA_CSS_ANYFUNCTION",
|
||||
"KATANA_CSS_CUEFUNCTION", "KATANA_CSS_NOTFUNCTION",
|
||||
"KATANA_CSS_CALCFUNCTION", "KATANA_CSS_MINFUNCTION",
|
||||
"KATANA_CSS_MAXFUNCTION", "KATANA_CSS_HOSTFUNCTION",
|
||||
"KATANA_CSS_HOSTCONTEXTFUNCTION", "KATANA_CSS_UNICODERANGE" };
|
||||
|
||||
static char * katana_token_string(int tok)
|
||||
{
|
||||
if (tok > 257)
|
||||
{
|
||||
return katana_token_table[tok-257];
|
||||
}
|
||||
else if ( 0 == tok )
|
||||
{
|
||||
return katana_token_table[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
char* unicode = malloc(2);
|
||||
unicode[0] = (char)tok;
|
||||
unicode[1] = '\0';
|
||||
return unicode;
|
||||
}
|
||||
}
|
||||
#endif // #if KATANA_FELX_DEBUG
|
||||
#endif // #ifdef KATANA_FELX_DEBUG
|
||||
|
||||
inline bool katana_is_html_space(char c)
|
||||
{
|
||||
return c <= ' ' && (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f');
|
||||
}
|
||||
|
||||
//inline int katana_to_ascii_hex_value(char c)
|
||||
//{
|
||||
// // ASSERT(isASCIIHexDigit(c));
|
||||
// return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF;
|
||||
//}
|
||||
|
||||
//inline bool katana_is_ascii_hex_digit(char c)
|
||||
//{
|
||||
// return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');
|
||||
//}
|
||||
41
Nuake/src/Vendors/katana-parser/tokenizer.h
Normal file
41
Nuake/src/Vendors/katana-parser/tokenizer.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2015 QFish <im@qfi.sh>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __Katana__tokenizer__
|
||||
#define __Katana__tokenizer__
|
||||
|
||||
#include <stdio.h>
|
||||
#include "katana.lex.h"
|
||||
#include "katana.tab.h"
|
||||
#include "parser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(__Katana__tokenizer__) */
|
||||
3098
Nuake/src/Vendors/nanosvg/nanosvg.h
Normal file
3098
Nuake/src/Vendors/nanosvg/nanosvg.h
Normal file
File diff suppressed because it is too large
Load Diff
1460
Nuake/src/Vendors/nanosvg/nanosvgrast.h
Normal file
1460
Nuake/src/Vendors/nanosvg/nanosvgrast.h
Normal file
File diff suppressed because it is too large
Load Diff
25
premake5.lua
25
premake5.lua
@@ -58,6 +58,8 @@ group "Dependencies"
|
||||
include "Nuake/dependencies/recastnavigation_p5.lua"
|
||||
include "Nuake/dependencies/tracy_p5.lua"
|
||||
include "Nuake/dependencies/yoga_p5.lua"
|
||||
include "Nuake/dependencies/msdf-atlas-gen_p5.lua"
|
||||
include "Nuake/dependencies/freetype_p5.lua"
|
||||
group ""
|
||||
|
||||
include "NuakeNet/premake5.lua"
|
||||
@@ -164,8 +166,13 @@ project "Nuake"
|
||||
"%{prj.name}/dependencies/recastnavigation/DetourCrowd/Include",
|
||||
"%{prj.name}/dependencies/recastnavigation/DetourTileCache/Include",
|
||||
"%{prj.name}/dependencies/recastnavigation/Recast/Include",
|
||||
|
||||
"%{prj.name}/dependencies/yoga",
|
||||
"%{prj.name}/dependencies/msdf-atlas-gen",
|
||||
"%{prj.name}/dependencies/msdf-atlas-gen/msdfgen",
|
||||
"%{prj.name}/dependencies/msdf-atlas-gen/msdfgen/include",
|
||||
"%{prj.name}/dependencies/freetype/include",
|
||||
"%{prj.name}/../Nuake/dependencies/tracy/public/tracy",
|
||||
|
||||
}
|
||||
|
||||
links
|
||||
@@ -381,6 +388,7 @@ project "Editor"
|
||||
{
|
||||
"%{prj.name}/../Nuake",
|
||||
"%{prj.name}/../Nuake/src/Vendors",
|
||||
"%{prj.name}/../Nuake/src/Vendors/nanosvg",
|
||||
"%{prj.name}/../Nuake/dependencies/glad/include",
|
||||
"%{prj.name}/../Nuake/dependencies/glfw/include",
|
||||
"%{prj.name}/../Nuake/dependencies/assimp/include",
|
||||
@@ -394,8 +402,13 @@ project "Editor"
|
||||
"%{prj.name}/../Nuake/dependencies/recastnavigation/DetourCrowd/Include",
|
||||
"%{prj.name}/../Nuake/dependencies/recastnavigation/DetourTileCache/Include",
|
||||
"%{prj.name}/../Nuake/dependencies/recastnavigation/Recast/Include",
|
||||
|
||||
"%{prj.name}/../Nuake/dependencies/yoga",
|
||||
"%{prj.name}/../Nuake/dependencies/msdf-atlas-gen",
|
||||
"%{prj.name}/../Nuake/dependencies/msdf-atlas-gen/msdfgen",
|
||||
"%{prj.name}/../Nuake/dependencies/msdf-atlas-gen/msdfgen/include",
|
||||
"%{prj.name}/../Nuake/dependencies/freetype/include",
|
||||
"%{prj.name}/../Nuake/dependencies/tracy/public/tracy",
|
||||
|
||||
}
|
||||
|
||||
libdirs
|
||||
@@ -406,7 +419,8 @@ project "Editor"
|
||||
"%{prj.name}/../Nuake/src/Vendors/wren/src/include",
|
||||
"%{prj.name}/../Nuake/dependencies/JoltPhysics/bin/%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}/JoltPhysics/",
|
||||
"%{prj.name}/../Nuake/dependencies/soloud/bin/%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}",
|
||||
"%{prj.name}/../Nuake/dependencies/Coral/NetCore/"
|
||||
"%{prj.name}/../Nuake/dependencies/Coral/NetCore/",
|
||||
"%{prj.name}/../Nuake/dependencies/freetype/bin/%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}/Freetype"
|
||||
}
|
||||
|
||||
links
|
||||
@@ -424,7 +438,10 @@ project "Editor"
|
||||
"DetourTileCache",
|
||||
"Recast",
|
||||
"tracy",
|
||||
"yoga"
|
||||
"yoga",
|
||||
"msdf-gen",
|
||||
"msdf-atlas-gen",
|
||||
"Freetype"
|
||||
}
|
||||
|
||||
defines {
|
||||
|
||||
Reference in New Issue
Block a user