From 93e58db8709aea8797e75f939e92379107a3afbd Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Mon, 19 Jul 2021 00:09:00 -0400 Subject: [PATCH] UI work --- Editor/Editor.cpp | 11 +- Editor/resources/Interface/Testing.css | 8 +- Editor/resources/Interface/Testing.interface | 6 +- Nuake/src/Core/Input.cpp | 2 +- Nuake/src/Scripting/VM.cpp | 16 + Nuake/src/Scripting/VM.h | 13 + Nuake/src/UI/InterfaceParser.cpp | 48 +-- Nuake/src/UI/Nodes/Node.cpp | 131 +++--- Nuake/src/UI/Nodes/Node.h | 413 ++++++++----------- Nuake/src/UI/Nodes/TextNode.h | 12 +- Nuake/src/UI/Styling/Style.h | 91 +++- Nuake/src/UI/Styling/StyleSheetParser.cpp | 18 + Nuake/src/UI/Styling/Stylesheet.h | 36 +- Nuake/src/UI/UserInterface.cpp | 70 +++- Nuake/src/UI/UserInterface.h | 13 +- 15 files changed, 500 insertions(+), 388 deletions(-) create mode 100644 Nuake/src/Scripting/VM.cpp create mode 100644 Nuake/src/Scripting/VM.h diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 7c08b370..82328796 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -30,7 +30,7 @@ int main() Ref lightTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png"); Ref camTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png"); Ref GuizmoShader = Nuake::ShaderManager::GetShader("resources/Shaders/gizmo.shader"); - Ref uinterface = Nuake::UI::UserInterface::New("Editor"); + Ref uinterface = Nuake::UI::UserInterface::New("Editor", "resources/Interface/Testing.interface"); while (!Nuake::Engine::GetCurrentWindow()->ShouldClose()) { @@ -39,18 +39,16 @@ int main() uinterface->Update(0.0f); Nuake::Engine::Draw(); - // + if (Nuake::Input::IsKeyPressed(GLFW_KEY_F1)) uinterface->Reload(); + if (Nuake::Input::IsKeyPressed(GLFW_KEY_F8)) Nuake::Engine::ExitPlayMode(); Nuake::Vector2 WindowSize = Nuake::Engine::GetCurrentWindow()->GetSize(); glViewport(0, 0, WindowSize.x, WindowSize.y); Nuake::Renderer2D::BeginDraw(WindowSize); - //Nuake::Renderer2D::DrawRect(Nuake::Vector2(100, 100), Nuake::Vector2(100, 100), Nuake::Color(1.0, 0.0, 0.0, 1.0), 2.0f); - - uinterface->Draw(WindowSize); Ref sceneFramebuffer = Nuake::Engine::GetCurrentWindow()->GetFrameBuffer(); @@ -97,9 +95,6 @@ int main() } sceneFramebuffer->Unbind(); - - //if (ImGui::Begin("test")) {} - //ImGui::End(); //editor.Draw(); Nuake::Engine::EndDraw(); } diff --git a/Editor/resources/Interface/Testing.css b/Editor/resources/Interface/Testing.css index f90e002b..3e40b00b 100644 --- a/Editor/resources/Interface/Testing.css +++ b/Editor/resources/Interface/Testing.css @@ -15,6 +15,7 @@ align-content: center; flex-direction: column; } + .panel { display: flex; height: 33%; @@ -32,7 +33,7 @@ } .panel-bottom { - width:100%; + width: 100%; height: 25%; justify-content: space-around; align-items: center; @@ -44,6 +45,11 @@ justify-content: space-around; align-items: center; align-content: center; + background-color: 18 18 18 255; +} + +.rect:hover { + background-color: 40 40 40 255; } .normal-text { diff --git a/Editor/resources/Interface/Testing.interface b/Editor/resources/Interface/Testing.interface index 69b1627a..6c4780ab 100644 --- a/Editor/resources/Interface/Testing.interface +++ b/Editor/resources/Interface/Testing.interface @@ -15,16 +15,14 @@ groups="rect" height="50px" width="49%" - border="8px 8px 8px 8px" - color="18 18 18 255"> + border="8px 8px 8px 8px">

New Project

+ border="8px 8px 8px 8px">

Load Project

diff --git a/Nuake/src/Core/Input.cpp b/Nuake/src/Core/Input.cpp index a1ea0144..b51756a6 100644 --- a/Nuake/src/Core/Input.cpp +++ b/Nuake/src/Core/Input.cpp @@ -139,7 +139,7 @@ namespace Nuake double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); - return Vector2(xpos, ypos); + return Vector2(xpos, ypos); } #pragma endregion diff --git a/Nuake/src/Scripting/VM.cpp b/Nuake/src/Scripting/VM.cpp new file mode 100644 index 00000000..c4f12df2 --- /dev/null +++ b/Nuake/src/Scripting/VM.cpp @@ -0,0 +1,16 @@ +#include "VM.h" + +namespace Nuake { + VM::VM() + { + WrenConfiguration config; + wrenInitConfiguration(&config); + + //config.loadModuleFn = &myLoadModule; + //config.errorFn = &errorFn; + //config.writeFn = &writeFn; + //config.bindForeignMethodFn = &bindForeignMethod; + + m_VM = wrenNewVM(&config); + } +} \ No newline at end of file diff --git a/Nuake/src/Scripting/VM.h b/Nuake/src/Scripting/VM.h new file mode 100644 index 00000000..9a8a5cb2 --- /dev/null +++ b/Nuake/src/Scripting/VM.h @@ -0,0 +1,13 @@ +#pragma once +#include + +namespace Nuake { + class VM + { + VM(); + + inline WrenVM* GetVM(); + private: + WrenVM* m_VM; + }; +} \ No newline at end of file diff --git a/Nuake/src/UI/InterfaceParser.cpp b/Nuake/src/UI/InterfaceParser.cpp index 71c8906f..22e4bbb4 100644 --- a/Nuake/src/UI/InterfaceParser.cpp +++ b/Nuake/src/UI/InterfaceParser.cpp @@ -49,7 +49,7 @@ namespace Nuake Ref node = CreateRef(); node->content = xml_node.text().as_string(); node->Type = NodeType::Text; - TextStyle style{ + TextStyle style { FontManager::GetFont("resources/Fonts/RobotoMono-Regular.ttf"), 0.5, Color(255, 255, 255, 255) @@ -66,29 +66,29 @@ namespace Nuake } } if (name == "height") - node->Height = GetUnit(a.value()); + node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") - node->Width = GetUnit(a.value()); + node->NormalStyle.Width = GetUnit(a.value()); if (name == "margin") - node->Margin = GetVec4Unit(a.value()); + node->NormalStyle.Margin = GetVec4Unit(a.value()); if (name == "padding") - node->Padding = GetVec4Unit(a.value()); + node->NormalStyle.Padding = GetVec4Unit(a.value()); if (name == "border") - node->Border = GetVec4Unit(a.value()); + node->NormalStyle.Border = GetVec4Unit(a.value()); if (name == "position") - node->Position = GetVec4Unit(a.value()); + node->NormalStyle.Position = GetVec4Unit(a.value()); if (name == "color") - node->BackgroundColor = GetColor(a.value()); + node->NormalStyle.BackgroundColor = GetColor(a.value()); if (name == "font-size") style.fontSize = std::stof(a.value()); } Vector2 minSize = Renderer2D::CalculateStringSize(node->content, style); - node->Width = { + node->NormalStyle.Width = { minSize.x, Layout::Unit::PIXEL }; - node->Height = { + node->NormalStyle.Height = { minSize.y, Layout::Unit::PIXEL }; @@ -114,19 +114,19 @@ namespace Nuake } } if (name == "height") - node->Height = GetUnit(a.value()); + node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") - node->Width = GetUnit(a.value()); + node->NormalStyle.Width = GetUnit(a.value()); if (name == "margin") - node->Margin = GetVec4Unit(a.value()); + node->NormalStyle.Margin = GetVec4Unit(a.value()); if (name == "padding") - node->Padding = GetVec4Unit(a.value()); + node->NormalStyle.Padding = GetVec4Unit(a.value()); if (name == "border") - node->Border = GetVec4Unit(a.value()); + node->NormalStyle.Border = GetVec4Unit(a.value()); if (name == "position") - node->Position = GetVec4Unit(a.value()); + node->NormalStyle.Position = GetVec4Unit(a.value()); if (name == "color") - node->BackgroundColor = GetColor(a.value()); + node->NormalStyle.BackgroundColor = GetColor(a.value()); if (name == "onclick") { std::string signature = a.value(); @@ -268,19 +268,19 @@ namespace Nuake } } if (name == "height") - node->Height = GetUnit(a.value()); + node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") - node->Width = GetUnit(a.value()); + node->NormalStyle.Width = GetUnit(a.value()); if (name == "margin") - node->Margin = GetVec4Unit(a.value()); + node->NormalStyle.Margin = GetVec4Unit(a.value()); if (name == "padding") - node->Padding = GetVec4Unit(a.value()); + node->NormalStyle.Padding = GetVec4Unit(a.value()); if (name == "border") - node->Border = GetVec4Unit(a.value()); + node->NormalStyle.Border = GetVec4Unit(a.value()); if (name == "position") - node->Position = GetVec4Unit(a.value()); + node->NormalStyle.Position = GetVec4Unit(a.value()); if (name == "color") - node->BackgroundColor = GetColor(a.value()); + node->NormalStyle.BackgroundColor = GetColor(a.value()); if (name == "script") { auto s = split(a.value(), ' '); diff --git a/Nuake/src/UI/Nodes/Node.cpp b/Nuake/src/UI/Nodes/Node.cpp index 5cbf0378..01ce04aa 100644 --- a/Nuake/src/UI/Nodes/Node.cpp +++ b/Nuake/src/UI/Nodes/Node.cpp @@ -6,109 +6,126 @@ namespace Nuake { Childrens = std::vector>(); Groups = std::vector(); - PositionType = Layout::PositionType::RELATIVE; - Position = Layout::LayoutVec4(); - Height = MaxHeight = MinHeight = Layout::LayoutUnit(); - Margin = Padding = Border = Layout::LayoutVec4(); - Direction = Layout::LayoutDirection::LTR; - FlexDirection = Layout::FlexDirection::ROW; - FlexWrap = Layout::FlexWrap::WRAP; - FlexGrow = 0.f; - FlexShrink = 1.f; - FlexBasis = 10.f; - AspectRatio = 1.f; - AlignItems = Layout::AlignItems::AUTO; - AlignSelf = Layout::AlignItems::AUTO; + + NormalStyle = { + Layout::PositionType::RELATIVE, + Layout::LayoutVec4(), + Layout::LayoutUnit(), Layout::LayoutUnit(), Layout::LayoutUnit(), + Layout::LayoutUnit(), Layout::LayoutUnit(), Layout::LayoutUnit(), + Layout::LayoutVec4(), + Layout::LayoutVec4(), + Layout::LayoutVec4(), + Color(), + Layout::LayoutDirection::LTR, + Layout::FlexDirection::ROW, + Layout::FlexWrap::WRAP, + 0.f, + 1.f, + 10.f, + 1.f, + Layout::JustifyContent(), + Layout::AlignItems::AUTO, + Layout::AlignItems::AUTO, + }; } - void Node::ApplyStyle(Ref stylegroup) + void Node::ApplyStyle(Ref stylegroup, StyleGroupSelector selector) { + Style style = NormalStyle; for (auto& s : stylegroup->GetProps()) { switch (s.first) { case PropType::HEIGHT: { - Height.Unit = (Layout::Unit)(s.second.type); + style.Height.Unit = (Layout::Unit)(s.second.type); float value = s.second.value.Number; - Height.Value = value; + style.Height.Value = value; } break; case PropType::MIN_HEIGHT: - MinHeight.Unit = (Layout::Unit)s.second.type; - MinHeight.Value = s.second.value.Number; + style.MinHeight.Unit = (Layout::Unit)s.second.type; + style.MinHeight.Value = s.second.value.Number; break; case PropType::MAX_HEIGHT: - MaxHeight.Unit = (Layout::Unit)s.second.type; - MaxHeight.Value = s.second.value.Number; + style.MaxHeight.Unit = (Layout::Unit)s.second.type; + style.MaxHeight.Value = s.second.value.Number; break; case PropType::WIDTH: - Width.Unit = (Layout::Unit)s.second.type; - Width.Value = s.second.value.Number; + style.Width.Unit = (Layout::Unit)s.second.type; + style.Width.Value = s.second.value.Number; break; case PropType::MIN_WIDTH: - MinWidth.Unit = (Layout::Unit)s.second.type; - MinWidth.Value = s.second.value.Number; + style.MinWidth.Unit = (Layout::Unit)s.second.type; + style.MinWidth.Value = s.second.value.Number; break; case PropType::MAX_WIDTH: - MaxWidth.Unit = (Layout::Unit)s.second.type; - MaxWidth.Value = s.second.value.Number; + style.MaxWidth.Unit = (Layout::Unit)s.second.type; + style.MaxWidth.Value = s.second.value.Number; break; case PropType::MARGIN_RIGHT: - Margin.Right.Unit = (Layout::Unit)s.second.type; - Margin.Right.Value = s.second.value.Number; + style.Margin.Right.Unit = (Layout::Unit)s.second.type; + style.Margin.Right.Value = s.second.value.Number; break; case PropType::MARGIN_LEFT: - Margin.Left.Unit = (Layout::Unit)s.second.type; - Margin.Left.Value = s.second.value.Number; + style.Margin.Left.Unit = (Layout::Unit)s.second.type; + style.Margin.Left.Value = s.second.value.Number; break; case PropType::MARGIN_TOP: - Margin.Top.Unit = (Layout::Unit)s.second.type; - Margin.Top.Value = s.second.value.Number; + style.Margin.Top.Unit = (Layout::Unit)s.second.type; + style.Margin.Top.Value = s.second.value.Number; break; case PropType::MARGIN_BOTTOM: - Margin.Bottom.Unit = (Layout::Unit)s.second.type; - Margin.Bottom.Value = s.second.value.Number; + style.Margin.Bottom.Unit = (Layout::Unit)s.second.type; + style.Margin.Bottom.Value = s.second.value.Number; break; case PropType::JUSTIFY_CONTENT: - JustifyContent = (Layout::JustifyContent)s.second.value.Enum; + style.JustifyContent = (Layout::JustifyContent)s.second.value.Enum; break; case PropType::FLEX_WRAP: - FlexWrap = (Layout::FlexWrap)s.second.value.Enum; + style.FlexWrap = (Layout::FlexWrap)s.second.value.Enum; break; case PropType::FLEX_DIRECTION: - FlexDirection = (Layout::FlexDirection)s.second.value.Enum; + style.FlexDirection = (Layout::FlexDirection)s.second.value.Enum; break; case PropType::ALIGN_ITEMS: - AlignItems = (Layout::AlignItems)s.second.value.Enum; + style.AlignItems = (Layout::AlignItems)s.second.value.Enum; break; case PropType::SELF_ALIGN: - AlignSelf = (Layout::AlignItems)s.second.value.Enum; + style.AlignSelf = (Layout::AlignItems)s.second.value.Enum; break; case PropType::ALIGN_CONTENT: - AlignContent = (Layout::AlignContent)s.second.value.Enum; + style.AlignContent = (Layout::AlignContent)s.second.value.Enum; break; case PropType::POSITION: - PositionType = (Layout::PositionType)s.second.value.Enum; + style.PositionType = (Layout::PositionType)s.second.value.Enum; break; case PropType::LEFT: - Position.Left.Unit = (Layout::Unit)s.second.type; - Position.Left.Value = s.second.value.Number; + style.Position.Left.Unit = (Layout::Unit)s.second.type; + style.Position.Left.Value = s.second.value.Number; break; case PropType::RIGHT: - Position.Right.Unit = (Layout::Unit)s.second.type; - Position.Right.Value = s.second.value.Number; + style.Position.Right.Unit = (Layout::Unit)s.second.type; + style.Position.Right.Value = s.second.value.Number; break; case PropType::TOP: - Position.Top.Unit = (Layout::Unit)s.second.type; - Position.Top.Value = s.second.value.Number; + style.Position.Top.Unit = (Layout::Unit)s.second.type; + style.Position.Top.Value = s.second.value.Number; break; case PropType::BOTTOM: - Position.Bottom.Unit = (Layout::Unit)s.second.type; - Position.Bottom.Value = s.second.value.Number; + style.Position.Bottom.Unit = (Layout::Unit)s.second.type; + style.Position.Bottom.Value = s.second.value.Number; + break; + case PropType::BACKGROUND_COLOR: + style.BackgroundColor = s.second.value.Color; break; } } + + if (selector == StyleGroupSelector::Hover) + HoverStyle = style; + else + NormalStyle = style; } bool Node::IsPositionInside(Vector2 position) @@ -122,19 +139,11 @@ namespace Nuake float parentLeft = 0.0f; float parentTop = 0.0f; auto parent = YGNodeGetParent(YogaNode); - if (parent) + while (parent) { - parentLeft = YGNodeLayoutGetLeft(YGNodeGetParent(YogaNode)); - parentTop = YGNodeLayoutGetTop(YGNodeGetParent(YogaNode)); - float parentPaddingTop = YGNodeLayoutGetPadding(parent, YGEdgeTop); - float parentPaddingLeft = YGNodeLayoutGetPadding(parent, YGEdgeTop); - // Overflow hidden. - float parentwidth = YGNodeLayoutGetWidth(parent); - if (parentwidth - YGNodeLayoutGetMargin(YogaNode, YGEdgeLeft) < width) - width = parentwidth - parentPaddingLeft; - float parentHeight = YGNodeLayoutGetHeight(parent); - if (parentHeight < height) - height = parentHeight - parentPaddingTop; + parentLeft += YGNodeLayoutGetLeft(parent); + parentTop += YGNodeLayoutGetTop(parent); + parent = YGNodeGetParent(parent); } left += parentLeft; diff --git a/Nuake/src/UI/Nodes/Node.h b/Nuake/src/UI/Nodes/Node.h index e6c527f0..8f84c9eb 100644 --- a/Nuake/src/UI/Nodes/Node.h +++ b/Nuake/src/UI/Nodes/Node.h @@ -8,71 +8,12 @@ namespace Nuake { - namespace Layout - { - enum class LayoutDirection - { - LTR = 2, RTL = 3 - }; - - enum class FlexWrap - { - NO_WRAP, WRAP, WRAP_REVERSED - }; - - enum class FlexDirection - { - ROW, COLUMN, ROW_REVERSED, COLUMN_REVERSED - }; - - enum class JustifyContent - { - FLEX_START, FLEX_END, CENTER, SPACE_BETWEEN, SPACE_AROUND, SPACE_EVENLY - }; - - enum class AlignItems - { - STRETCH, FLEX_START, FLEX_END, CENTER, BASELINE, AUTO, - }; - - enum class AlignContent - { - FLEX_START, FLEX_END, STRETCH, CENTER, SPACE_BETWEEN, SPACE_AROUND - }; - - enum class PositionType - { - STATIC, RELATIVE, ABSOLUTE - }; - - enum Unit - { - PIXEL, PERCENT, AUTO - }; - - struct LayoutUnit - { - float Value = 0.0f; - Unit Unit = Unit::PIXEL; - }; - - struct LayoutVec4 - { - LayoutUnit Top = LayoutUnit{ 0, PIXEL }; - LayoutUnit Bottom = LayoutUnit{ 0, PIXEL }; - LayoutUnit Left = LayoutUnit{ 0, PIXEL }; - LayoutUnit Right = LayoutUnit{ 0, PIXEL }; - }; - } - - enum class NodeType { Normal, Text }; - // Base UI node. class Node { public: @@ -88,31 +29,13 @@ namespace Nuake YGNodeRef YogaNode; - Ref