diff --git a/engine/includes/components/animator.h b/engine/includes/components/animator.h index 5b9fef144..79754b4b6 100644 --- a/engine/includes/components/animator.h +++ b/engine/includes/components/animator.h @@ -3,6 +3,8 @@ #include "nativebehaviour.h" +#include "animationstatemachine.h" + class AnimationClip; class AnimationStateMachine; class AnimationState; diff --git a/engine/includes/editor/viewport/viewport.h b/engine/includes/editor/viewport/viewport.h index 2dea2306d..4c5bd27d9 100644 --- a/engine/includes/editor/viewport/viewport.h +++ b/engine/includes/editor/viewport/viewport.h @@ -23,7 +23,7 @@ class ENGINE_EXPORT Viewport : public QWidget { virtual void init(); - CameraController *controllder(); + CameraController *controller(); void setController(CameraController *ctrl); virtual void setWorld(World *world); diff --git a/engine/includes/resources/resource.h b/engine/includes/resources/resource.h index 21ac9542e..9da41d302 100644 --- a/engine/includes/resources/resource.h +++ b/engine/includes/resources/resource.h @@ -5,8 +5,6 @@ #include - - class ENGINE_EXPORT Resource : public Object { A_REGISTER(Resource, Object, General) diff --git a/engine/src/components/actor.cpp b/engine/src/components/actor.cpp index 19b9aef4c..bdb8821d4 100644 --- a/engine/src/components/actor.cpp +++ b/engine/src/components/actor.cpp @@ -105,6 +105,10 @@ void Actor::setEnabled(const bool enabled) { } setHierarchyEnabled(enabled); + + if(m_transform) { + m_transform->setEnabled(enabled); + } } /*! Returns a set of Actor::HideFlags applied to this Actor. diff --git a/engine/src/components/transform.cpp b/engine/src/components/transform.cpp index efaf14108..db408794b 100644 --- a/engine/src/components/transform.cpp +++ b/engine/src/components/transform.cpp @@ -147,6 +147,11 @@ void Transform::setParentTransform(Transform *parent, bool force) { return; } + if(parent && actor()->parent() != parent->actor()) { + actor()->setParent(parent->actor()); + return; + } + Vector3 p; Vector3 e; Vector3 s; @@ -185,60 +190,42 @@ void Transform::setParentTransform(Transform *parent, bool force) { Returns current transform matrix in local space. */ const Matrix4 &Transform::localTransform() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_transform; } /*! Returns current transform matrix in world space. */ const Matrix4 &Transform::worldTransform() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_worldTransform; } /*! Returns current position of the transform in world space. */ Vector3 Transform::worldPosition() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return Vector3(m_worldTransform[12], m_worldTransform[13], m_worldTransform[14]); } /*! Returns current rotation of the transform in world space as Euler angles in degrees. */ Vector3 Transform::worldRotation() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_worldRotation; } /*! Returns current rotation of the transform in world space as Quaternion. */ Quaternion Transform::worldQuaternion() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_worldQuaternion; } /*! Returns current scale of the transform in world space. */ Vector3 Transform::worldScale() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_worldScale; } /*! @@ -261,10 +248,7 @@ void Transform::setParent(Object *parent, int32_t position, bool force) { \internal */ uint32_t Transform::hash() const { - if(m_dirty) { - std::unique_lock locker(m_mutex); - cleanDirty(); - } + cleanDirty(); return m_hash; } /*! @@ -275,20 +259,24 @@ const std::list &Transform::children() const { } void Transform::cleanDirty() const { - m_transform = Matrix4(m_position, m_quaternion, m_scale); - m_worldTransform = m_transform; - m_worldRotation = m_rotation; - m_worldQuaternion = m_quaternion; - m_worldScale = m_scale; - if(m_parent) { - m_worldScale = m_parent->worldScale() * m_worldScale; - m_worldRotation = m_parent->worldRotation() + m_worldRotation; - m_worldQuaternion = m_parent->worldQuaternion() * m_worldQuaternion; - m_worldTransform = m_parent->worldTransform() * m_worldTransform; - } - m_hash = 16; - for(int i = 0; i < 16; i++) { - Mathf::hashCombine(m_hash, m_worldTransform[i]); + if(m_dirty) { + std::unique_lock locker(m_mutex); + + m_transform = Matrix4(m_position, m_quaternion, m_scale); + m_worldTransform = m_transform; + m_worldRotation = m_rotation; + m_worldQuaternion = m_quaternion; + m_worldScale = m_scale; + if(m_parent) { + m_worldScale = m_parent->worldScale() * m_worldScale; + m_worldRotation = m_parent->worldRotation() + m_worldRotation; + m_worldQuaternion = m_parent->worldQuaternion() * m_worldQuaternion; + m_worldTransform = m_parent->worldTransform() * m_worldTransform; + } + m_hash = 16; + for(int i = 0; i < 16; i++) { + Mathf::hashCombine(m_hash, m_worldTransform[i]); + } + m_dirty = false; } - m_dirty = false; } diff --git a/engine/src/editor/viewport/viewport.cpp b/engine/src/editor/viewport/viewport.cpp index ee671a213..10f966e2b 100644 --- a/engine/src/editor/viewport/viewport.cpp +++ b/engine/src/editor/viewport/viewport.cpp @@ -530,7 +530,7 @@ void Viewport::init() { } } -CameraController *Viewport::controllder() { +CameraController *Viewport::controller() { return m_controller; } diff --git a/engine/src/engine.cpp b/engine/src/engine.cpp index 1d28d0a5d..bb38f223f 100644 --- a/engine/src/engine.cpp +++ b/engine/src/engine.cpp @@ -34,29 +34,8 @@ #else #include "adapters/desktopadaptor.h" #endif -#include "resources/text.h" -#include "resources/texture.h" -#include "resources/rendertarget.h" -#include "resources/material.h" -#include "resources/mesh.h" -#include "resources/font.h" -#include "resources/animationclip.h" -#include "resources/animationstatemachine.h" -#include "resources/translator.h" -#include "resources/particleeffect.h" -#include "resources/pipeline.h" -#include "resources/pose.h" -#include "resources/prefab.h" -#include "resources/map.h" -#include "resources/computebuffer.h" -#include "resources/computeshader.h" - -#include "resources/meshgroup.h" -#include "resources/controlscheme.h" - -#include "resources/tileset.h" -#include "resources/tilemap.h" +#include "resources/translator.h" #include "systems/resourcesystem.h" #include "systems/rendersystem.h" @@ -157,37 +136,6 @@ Engine::Engine(File *file, const char *path) { m_file = file; - // The order is critical for the import - Resource::registerClassFactory(m_resourceSystem); - - Text::registerClassFactory(m_resourceSystem); - Texture::registerClassFactory(m_resourceSystem); - Material::registerClassFactory(m_resourceSystem); - Mesh::registerClassFactory(m_resourceSystem); - MeshGroup::registerClassFactory(m_resourceSystem); - Sprite::registerClassFactory(m_resourceSystem); - Font::registerClassFactory(m_resourceSystem); - AnimationClip::registerClassFactory(m_resourceSystem); - RenderTarget::registerClassFactory(m_resourceSystem); - - Translator::registerClassFactory(m_resourceSystem); - Pose::registerSuper(m_resourceSystem); - - Prefab::registerClassFactory(m_resourceSystem); - Map::registerClassFactory(m_resourceSystem); - - TileSet::registerClassFactory(m_resourceSystem); - TileMap::registerClassFactory(m_resourceSystem); - - ParticleEffect::registerClassFactory(m_resourceSystem); - - AnimationStateMachine::registerSuper(m_resourceSystem); - - Pipeline::registerClassFactory(m_resourceSystem); - - ComputeBuffer::registerClassFactory(m_resourceSystem); - ComputeShader::registerClassFactory(m_resourceSystem); - World::registerClassFactory(m_instance); Scene::registerClassFactory(m_instance); Actor::registerClassFactory(m_instance); @@ -201,7 +149,6 @@ Engine::Engine(File *file, const char *path) { Armature::registerClassFactory(m_instance); - ControlScheme::registerClassFactory(m_resourceSystem); PlayerInput::registerClassFactory(m_instance); m_world = ObjectSystem::objectCreate("World"); diff --git a/engine/src/systems/resourcesystem.cpp b/engine/src/systems/resourcesystem.cpp index 74963371f..123286193 100644 --- a/engine/src/systems/resourcesystem.cpp +++ b/engine/src/systems/resourcesystem.cpp @@ -10,9 +10,65 @@ #include "resources/resource.h" +#include "resources/text.h" +#include "resources/texture.h" +#include "resources/rendertarget.h" +#include "resources/material.h" +#include "resources/mesh.h" +#include "resources/font.h" +#include "resources/animationclip.h" +#include "resources/animationstatemachine.h" +#include "resources/translator.h" +#include "resources/particleeffect.h" +#include "resources/pipeline.h" +#include "resources/pose.h" +#include "resources/prefab.h" +#include "resources/map.h" +#include "resources/computebuffer.h" +#include "resources/computeshader.h" + +#include "resources/meshgroup.h" + +#include "resources/controlscheme.h" + +#include "resources/tileset.h" +#include "resources/tilemap.h" + ResourceSystem::ResourceSystem() { setName("ResourceSystem"); + // The order is critical for the import + Resource::registerClassFactory(this); + + Text::registerClassFactory(this); + Texture::registerClassFactory(this); + Material::registerClassFactory(this); + Mesh::registerClassFactory(this); + MeshGroup::registerClassFactory(this); + Sprite::registerClassFactory(this); + Font::registerClassFactory(this); + AnimationClip::registerClassFactory(this); + RenderTarget::registerClassFactory(this); + + Translator::registerClassFactory(this); + Pose::registerSuper(this); + + Prefab::registerClassFactory(this); + Map::registerClassFactory(this); + + TileSet::registerClassFactory(this); + TileMap::registerClassFactory(this); + + ParticleEffect::registerClassFactory(this); + + AnimationStateMachine::registerSuper(this); + + Pipeline::registerClassFactory(this); + + ComputeBuffer::registerClassFactory(this); + ComputeShader::registerClassFactory(this); + + ControlScheme::registerClassFactory(this); } bool ResourceSystem::init() { diff --git a/modules/editor/grapheditor/editor/graph/graphview.cpp b/modules/editor/grapheditor/editor/graph/graphview.cpp index 46e1fac92..5079c0547 100644 --- a/modules/editor/grapheditor/editor/graph/graphview.cpp +++ b/modules/editor/grapheditor/editor/graph/graphview.cpp @@ -50,7 +50,7 @@ class ObjectObserver : public Object { void onNodePressed() { if(m_view) { - GraphController *ctrl = dynamic_cast(m_view->controllder()); + GraphController *ctrl = dynamic_cast(m_view->controller()); if(ctrl) { ctrl->setFocusNode(dynamic_cast(sender())); } @@ -339,6 +339,10 @@ void GraphView::showMenu() { } } +void GraphView::selectNode(GraphNode *node) { + static_cast(m_controller)->setSelected({node}); +} + void GraphView::onComponentSelected() { AbstractNodeGraph *g = graph(); diff --git a/modules/editor/grapheditor/editor/graph/graphview.h b/modules/editor/grapheditor/editor/graph/graphview.h index 865c8ae63..0b17779d8 100644 --- a/modules/editor/grapheditor/editor/graph/graphview.h +++ b/modules/editor/grapheditor/editor/graph/graphview.h @@ -39,6 +39,8 @@ class NODEGRAPH_EXPORT GraphView : public Viewport { void showMenu(); + void selectNode(GraphNode *node); + signals: void itemsSelected(const QList &); diff --git a/modules/editor/grapheditor/editor/graph/graphwidgets/nodewidget.cpp b/modules/editor/grapheditor/editor/graph/graphwidgets/nodewidget.cpp index 78c97ab3e..84d228605 100644 --- a/modules/editor/grapheditor/editor/graph/graphwidgets/nodewidget.cpp +++ b/modules/editor/grapheditor/editor/graph/graphwidgets/nodewidget.cpp @@ -49,6 +49,8 @@ void NodeWidget::setGraphNode(GraphNode *node) { m_title->setColor(m_node->color()); } + rectTransform()->setSize(m_node->defaultSize()); + // Call ports for(NodePort &port : m_node->ports()) { if(port.m_call) { @@ -69,20 +71,6 @@ void NodeWidget::setGraphNode(GraphNode *node) { composePort(port); } } - - RectTransform *rect = rectTransform(); - Layout *layout = rect->layout(); - - Vector2 size = m_node->defaultSize(); - if(!m_node->ports().empty()) { - size.y = (m_node->ports().size() + 2.0f) * row; - if(layout) { - size.y = layout->sizeHint().y; - layout->update(); - } - } - - rect->setSize(size); } void NodeWidget::updateName() { @@ -164,6 +152,8 @@ void NodeWidget::composeComponent() { RectTransform *rect = rectTransform(); rect->setPivot(Vector2(0.0f, 1.0f)); rect->setLayout(layout); + rect->setVerticalPolicy(RectTransform::Preferred); + rect->setHorizontalPolicy(RectTransform::Fixed); Actor *title = Engine::composeActor(gFrame, "Title", actor()); if(title) { @@ -194,7 +184,7 @@ void NodeWidget::composeComponent() { } void NodeWidget::composePort(NodePort &port) { - Actor *portActor = Engine::composeActor(gPortWidget, port.m_name.c_str(), actor()); + Actor *portActor = Engine::composeActor(gPortWidget, port.m_name, actor()); if(portActor) { PortWidget *portWidget = static_cast(portActor->component(gPortWidget)); diff --git a/modules/editor/shadertools/converter/functions/function.cpp b/modules/editor/shadertools/converter/functions/function.cpp index 1d94729a5..d6f2689aa 100644 --- a/modules/editor/shadertools/converter/functions/function.cpp +++ b/modules/editor/shadertools/converter/functions/function.cpp @@ -261,14 +261,7 @@ void ShaderNode::switchPreview() { RectTransform *rect = m_nodeWidget->rectTransform(); Layout *layout = rect->layout(); - Vector2 size = rect->size(); - - if(layout) { - size.y = layout->sizeHint().y; - layout->invalidate(); - } - - rect->setSize(size); + layout->invalidate(); } Widget *ShaderNode::widget() { diff --git a/modules/editor/shadertools/converter/shadergraph.cpp b/modules/editor/shadertools/converter/shadergraph.cpp index 618d17d7f..f7eb97642 100644 --- a/modules/editor/shadertools/converter/shadergraph.cpp +++ b/modules/editor/shadertools/converter/shadergraph.cpp @@ -256,14 +256,14 @@ ShaderGraph::~ShaderGraph() { void ShaderGraph::scanForCustomFunctions() { QStringList filter({"*.mtlf"}); - QStringList files; - QStringList paths = { ":/shaders/functions", ProjectSettings::instance()->contentPath() }; for(auto &path : paths) { + QStringList files; + QDirIterator it(path, filter, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while(it.hasNext()) { files << it.next(); diff --git a/modules/uikit/includes/components/abstractbutton.h b/modules/uikit/includes/components/abstractbutton.h index 5c6520644..5980f5936 100644 --- a/modules/uikit/includes/components/abstractbutton.h +++ b/modules/uikit/includes/components/abstractbutton.h @@ -25,7 +25,8 @@ class UIKIT_EXPORT AbstractButton : public Widget { ) A_METHODS( A_SIGNAL(AbstractButton::pressed), - A_SIGNAL(AbstractButton::clicked) + A_SIGNAL(AbstractButton::clicked), + A_SIGNAL(AbstractButton::toggled) ) public: @@ -73,6 +74,8 @@ class UIKIT_EXPORT AbstractButton : public Widget { void pressed(); void clicked(); + void toggled(bool checked); + protected: void onReferenceDestroyed() override; @@ -86,8 +89,6 @@ class UIKIT_EXPORT AbstractButton : public Widget { virtual void checkStateSet(); protected: - std::string m_text; - Vector4 m_normalColor; Vector4 m_highlightedColor; Vector4 m_pressedColor; diff --git a/modules/uikit/includes/components/foldout.h b/modules/uikit/includes/components/foldout.h new file mode 100644 index 000000000..ca2640513 --- /dev/null +++ b/modules/uikit/includes/components/foldout.h @@ -0,0 +1,41 @@ +#ifndef FOLDOUT_H +#define FOLDOUT_H + +#include "widget.h" + +class Button; +class Frame; +class Label; + +class UIKIT_EXPORT Foldout : public Widget { + A_REGISTER(Foldout, Widget, Components/UI) + + A_METHODS( + A_SLOT(Foldout::onExpand) + ) + +public: + Foldout(); + + void addWidget(Widget *widget); + + bool isExpanded() const; + void setExpanded(bool expanded); + + std::string text() const; + void setText(const std::string text); + + void onExpand(); + +private: + void composeComponent() override; + +private: + Frame *m_container; + + Button *m_indicator; + + Label *m_label; +}; + +#endif // FOLDOUT_H diff --git a/modules/uikit/includes/components/frame.h b/modules/uikit/includes/components/frame.h index 15ada0eb2..d922cf901 100644 --- a/modules/uikit/includes/components/frame.h +++ b/modules/uikit/includes/components/frame.h @@ -44,7 +44,7 @@ class UIKIT_EXPORT Frame : public Widget { void setBorderColor(Vector4 color); protected: - void boundChanged(const Vector2 &bounds) override; + void boundChanged(const Vector2 &size) override; void draw(CommandBuffer &buffer) override; diff --git a/modules/uikit/includes/components/image.h b/modules/uikit/includes/components/image.h index ed0a30482..7a610b354 100644 --- a/modules/uikit/includes/components/image.h +++ b/modules/uikit/includes/components/image.h @@ -62,7 +62,7 @@ class UIKIT_EXPORT Image : public Widget { void loadUserData(const VariantMap &data) override; VariantMap saveUserData() const override; - void boundChanged(const Vector2 &bounds) override; + void boundChanged(const Vector2 &size) override; void composeMesh(); diff --git a/modules/uikit/includes/components/recttransform.h b/modules/uikit/includes/components/recttransform.h index ea26cdbea..3121a56e7 100644 --- a/modules/uikit/includes/components/recttransform.h +++ b/modules/uikit/includes/components/recttransform.h @@ -22,6 +22,14 @@ class UIKIT_EXPORT RectTransform : public Transform { ) A_NOMETHODS() + enum SizePolicy { + Fixed = 0, + Minimum, + Maximum, + Preferred + }; + +public: RectTransform(); ~RectTransform(); @@ -63,16 +71,22 @@ class UIKIT_EXPORT RectTransform : public Transform { AABBox bound() const; + void setEnabled(bool enabled) override; + + SizePolicy verticalPolicy() const; + void setVerticalPolicy(SizePolicy policy); + + SizePolicy horizontalPolicy() const; + void setHorizontalPolicy(SizePolicy policy); + private: friend class Layout; - void setDirty() override; - void cleanDirty() const override; - void notify() const; + void recalcChilds() const; - void recalcSize() const; + void recalcParent(); private: std::list m_subscribers; @@ -89,6 +103,9 @@ class UIKIT_EXPORT RectTransform : public Transform { Layout *m_layout; Layout *m_attachedLayout; + SizePolicy m_verticalPolicy; + SizePolicy m_horizontalPolicy; + bool m_mouseTracking; mutable bool m_flag = false; diff --git a/modules/uikit/includes/components/widget.h b/modules/uikit/includes/components/widget.h index bfbe262b3..46c5f91d2 100644 --- a/modules/uikit/includes/components/widget.h +++ b/modules/uikit/includes/components/widget.h @@ -48,8 +48,6 @@ class UIKIT_EXPORT Widget : public NativeBehaviour { void setRectTransform(RectTransform *transform); - void update() override; - void actorParentChanged() override; void composeComponent() override; diff --git a/modules/uikit/src/components/abstractbutton.cpp b/modules/uikit/src/components/abstractbutton.cpp index 8a3994c91..227a4b108 100644 --- a/modules/uikit/src/components/abstractbutton.cpp +++ b/modules/uikit/src/components/abstractbutton.cpp @@ -54,13 +54,15 @@ AbstractButton::AbstractButton() : Returns the text displayed on the button. */ std::string AbstractButton::text() const { - return m_text; + if(m_label) { + return m_label->text(); + } + return std::string(); } /*! Sets the \a text displayed on the button. */ void AbstractButton::setText(const std::string text) { - m_text = text; if(m_label) { m_label->setText(text); } @@ -217,6 +219,8 @@ bool AbstractButton::isChecked() const { void AbstractButton::setChecked(bool checked) { m_checked = checked; checkStateSet(); + + emitSignal(_SIGNAL(toggled(bool)), m_checked); } /*! Returns true if the button is in exclusive mode; otherwise, false. diff --git a/modules/uikit/src/components/button.cpp b/modules/uikit/src/components/button.cpp index 6d0783016..eeb23d7d7 100644 --- a/modules/uikit/src/components/button.cpp +++ b/modules/uikit/src/components/button.cpp @@ -1,15 +1,10 @@ #include "components/button.h" #include "components/label.h" -#include "components/frame.h" #include "components/image.h" +#include "components/frame.h" #include "components/recttransform.h" -#include -#include - -#include - /*! \class Button \brief The Button class represents a push button class. diff --git a/modules/uikit/src/components/foldout.cpp b/modules/uikit/src/components/foldout.cpp new file mode 100644 index 000000000..bc7fa306f --- /dev/null +++ b/modules/uikit/src/components/foldout.cpp @@ -0,0 +1,133 @@ +#include "components/foldout.h" + +#include "components/label.h" +#include "components/frame.h" +#include "components/image.h" +#include "components/button.h" +#include "components/recttransform.h" +#include "components/layout.h" + +#include + +namespace { + const char *gButton("Button"); + const char *gFrame("Frame"); + const char *gLabel("Label"); +} + +Foldout::Foldout() : + m_container(nullptr), + m_indicator(nullptr), + m_label(nullptr) { + +} + +void Foldout::addWidget(Widget *widget) { + if(m_container) { + widget->rectTransform()->setParentTransform(m_container->rectTransform()); + + Layout *layout = m_container->rectTransform()->layout(); + if(layout) { + layout->addTransform(widget->rectTransform()); + } + } +} + +bool Foldout::isExpanded() const { + if(m_container) { + return m_container->actor()->isEnabled(); + } + return false; +} + +void Foldout::setExpanded(bool expanded) { + if(m_container) { + m_container->actor()->setEnabled(expanded); + + Image *icon = m_indicator->icon(); + if(icon) { + RectTransform *rect = icon->rectTransform(); + if(rect) { + rect->setRotation(Vector3(0.0f, 0.0f, expanded ? 0.0f : 90.0f)); + } + } + + RectTransform *rect = rectTransform(); + Layout *layout = rect->layout(); + + layout->invalidate(); + } +} + +std::string Foldout::text() const { + if(m_label) { + return m_label->text(); + } + return std::string(); +} + +void Foldout::setText(const std::string text) { + if(m_label) { + m_label->setText(text); + } +} + +void Foldout::onExpand() { + setExpanded(!isExpanded()); +} + +void Foldout::composeComponent() { + Widget::composeComponent(); + + Actor *container = Engine::composeActor(gFrame, "Container", actor()); + m_container = container->getComponent(); + m_container->setColor(Vector4(0.0f, 0.0f, 0.0f, 0.25f)); + + RectTransform *containerRect = m_container->rectTransform(); + containerRect->setAnchors(0.0f, 1.0f); + containerRect->setPivot(Vector2(0.0f, 0.0f)); + containerRect->setVerticalPolicy(RectTransform::Preferred); + + Layout *containerLayout = new Layout; + containerRect->setLayout(containerLayout); + + Actor *indicator = Engine::composeActor(gButton, "Indicator", actor()); + m_indicator = indicator->getComponent