Ver código fonte

Object and effect visibility can now be compared to project's properties

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
Alexis Maiquez 3 anos atrás
pai
commit
fc150576eb

+ 5 - 0
CMakeLists.txt

@@ -116,6 +116,11 @@ add_executable(
         src/WallpaperEngine/Core/Types/FloatColor.h
         src/WallpaperEngine/Core/Types/IntegerColor.h
 
+        src/WallpaperEngine/Core/UserSettings/CUserSettingValue.cpp
+        src/WallpaperEngine/Core/UserSettings/CUserSettingValue.h
+        src/WallpaperEngine/Core/UserSettings/CUserSettingBoolean.cpp
+        src/WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h
+
         src/WallpaperEngine/Core/CProject.cpp
         src/WallpaperEngine/Core/CProject.h
         src/WallpaperEngine/Core/CWallpaper.cpp

+ 34 - 13
src/WallpaperEngine/Core/CObject.cpp

@@ -1,23 +1,29 @@
 #include "CObject.h"
 
 #include <utility>
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
 #include "WallpaperEngine/Core/Objects/CImage.h"
 #include "WallpaperEngine/Core/Objects/CSound.h"
 #include "WallpaperEngine/Core/Objects/CParticle.h"
+#include "WallpaperEngine/Core/CScene.h"
+#include "WallpaperEngine/Core/CProject.h"
 
 #include "WallpaperEngine/Assets/CContainer.h"
 
 using namespace WallpaperEngine::Core;
 using namespace WallpaperEngine::Assets;
+using namespace WallpaperEngine::Core::UserSettings;
 
 CObject::CObject (
-        bool visible,
+        CScene* scene,
+        CUserSettingBoolean* visible,
         uint32_t id,
         std::string name,
         std::string type,
         const glm::vec3& origin,
         const glm::vec3& scale,
         const glm::vec3& angles) :
+    m_scene (scene),
     m_visible (visible),
     m_id (id),
     m_name (std::move(name)),
@@ -28,12 +34,19 @@ CObject::CObject (
 {
 }
 
-CObject* CObject::fromJSON (json data, const CContainer* container)
+CObject* CObject::fromJSON (json data, CScene* scene, const CContainer* container)
 {
     std::string json = data.dump ();
 
     auto id_it = jsonFindRequired (data, "id", "Objects must have id");
-    auto visible = jsonFindUserConfig (data, "visible", false);
+    auto visible_it = data.find ("visible");
+    CUserSettingBoolean* visible;
+
+    if (visible_it == data.end ())
+        visible = CUserSettingBoolean::fromScalar (true);
+    else
+        visible = CUserSettingBoolean::fromJSON (*visible_it);
+
     auto origin_val = jsonFindDefault <std::string> (data, "origin", "0.0 0.0 0.0");
     auto scale_val = jsonFindDefault <std::string> (data, "scale", "0.0 0.0 0.0");
     auto angles_val = jsonFindDefault <std::string> (data, "angles", "0.0 0.0 0.0");
@@ -51,11 +64,8 @@ CObject* CObject::fromJSON (json data, const CContainer* container)
 
     if (image_it != data.end () && (*image_it).is_null () == false)
     {
-        // composelayer should be ignored for now, or artifacts will appear
-        if (*image_it == "models/util/composelayer.json")
-            return nullptr;
-
         object = Objects::CImage::fromJSON (
+                scene,
                 data,
                 container,
                 visible,
@@ -69,6 +79,7 @@ CObject* CObject::fromJSON (json data, const CContainer* container)
     else if (sound_it != data.end () && (*sound_it).is_null () == false)
     {
         object = Objects::CSound::fromJSON (
+                scene,
                 data,
                 visible,
                 *id_it,
@@ -84,8 +95,10 @@ CObject* CObject::fromJSON (json data, const CContainer* container)
         try
         {
             object = Objects::CParticle::fromFile (
+                scene,
                 (*particle_it).get <std::string> (),
                 container,
+                visible,
                 *id_it,
                 *name_it,
                 WallpaperEngine::Core::aToVector3 (origin_val),
@@ -119,14 +132,16 @@ CObject* CObject::fromJSON (json data, const CContainer* container)
 
         for (; cur != end; cur ++)
         {
-            // check if the effect is visible or not
-            auto effectVisible = jsonFindUserConfig (*cur, "visible", true);
+            auto effectVisible_it = data.find ("visible");
+            CUserSettingBoolean* effectVisible;
 
-            if (effectVisible == false)
-                continue;
+            if (effectVisible_it == data.end ())
+                effectVisible = CUserSettingBoolean::fromScalar (true);
+            else
+                effectVisible = CUserSettingBoolean::fromJSON (*effectVisible_it);
 
             object->insertEffect (
-                Objects::CEffect::fromJSON (*cur, object, container)
+                Objects::CEffect::fromJSON (*cur, effectVisible, object, container)
             );
         }
     }
@@ -177,7 +192,13 @@ const std::vector<uint32_t>& CObject::getDependencies () const
 
 const bool CObject::isVisible () const
 {
-    return this->m_visible;
+    // TODO: cache this
+    return this->m_visible->processValue (this->getScene ()->getProject ()->getProperties ());
+}
+
+CScene* CObject::getScene () const
+{
+    return this->m_scene;
 }
 
 const int CObject::getId () const

+ 20 - 3
src/WallpaperEngine/Core/CObject.h

@@ -4,21 +4,34 @@
 
 #include "WallpaperEngine/Core/Objects/CEffect.h"
 #include "WallpaperEngine/Assets/CContainer.h"
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
+
+namespace WallpaperEngine::Core
+{
+    class CScene;
+}
 
 namespace WallpaperEngine::Core::Objects
 {
     class CEffect;
 }
 
+namespace WallpaperEngine::Core::UserSettings
+{
+    class CUserSettingBoolean;
+}
+
 namespace WallpaperEngine::Core
 {
     using json = nlohmann::json;
     using namespace WallpaperEngine::Assets;
+    using namespace WallpaperEngine::Core::UserSettings;
 
     class CObject
     {
+        friend class CScene;
     public:
-        static CObject* fromJSON (json data, const CContainer* container);
+        static CObject* fromJSON (json data, CScene* scene, const CContainer* container);
 
         template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
         template<class T> T* as () { assert (is <T> ()); return (T*) this; }
@@ -35,9 +48,11 @@ namespace WallpaperEngine::Core
         const std::string& getName () const;
 
         const bool isVisible () const;
+        CScene* getScene () const;
     protected:
         CObject (
-            bool visible,
+            CScene* scene,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             std::string type,
@@ -51,7 +66,7 @@ namespace WallpaperEngine::Core
     private:
         std::string m_type;
 
-        bool m_visible;
+        CUserSettingBoolean* m_visible;
         uint32_t m_id;
         std::string m_name;
         glm::vec3 m_origin;
@@ -60,5 +75,7 @@ namespace WallpaperEngine::Core
 
         std::vector<Objects::CEffect*> m_effects;
         std::vector<uint32_t> m_dependencies;
+
+        CScene* m_scene;
     };
 };

+ 1 - 1
src/WallpaperEngine/Core/CScene.cpp

@@ -106,7 +106,7 @@ CScene* CScene::fromFile (const std::string& filename, CContainer* container)
     for (; cur != end; cur ++)
     {
         scene->insertObject (
-                CObject::fromJSON (*cur, container)
+                CObject::fromJSON (*cur, scene, container)
         );
     }
 

+ 17 - 4
src/WallpaperEngine/Core/Objects/CEffect.cpp

@@ -3,32 +3,39 @@
 #include <utility>
 #include <iostream>
 
+#include "WallpaperEngine/Core/CScene.h"
+#include "WallpaperEngine/Core/CProject.h"
 #include "WallpaperEngine/Core/Objects/CImage.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
 #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
 
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
+
 #include "WallpaperEngine/FileSystem/FileSystem.h"
 
 using namespace WallpaperEngine;
 using namespace WallpaperEngine::Core::Objects;
+using namespace WallpaperEngine::Core::UserSettings;
 
 CEffect::CEffect (
         std::string name,
         std::string description,
         std::string group,
         std::string preview,
-        Core::CObject* object):
+        Core::CObject* object,
+        CUserSettingBoolean* visible):
     m_name (std::move(name)),
     m_description (std::move(description)),
     m_group (std::move(group)),
     m_preview (std::move(preview)),
-    m_object (object)
+    m_object (object),
+    m_visible (visible)
 {
 }
 
-CEffect* CEffect::fromJSON (json data, Core::CObject* object, const CContainer* container)
+CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer* container)
 {
     auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
     auto effectpasses_it = data.find ("passes");
@@ -48,7 +55,8 @@ CEffect* CEffect::fromJSON (json data, Core::CObject* object, const CContainer*
         description,
         *group_it,
         preview,
-        object
+        object,
+        visible
     );
 
     CEffect::materialsFromJSON (passes_it, effect, container);
@@ -275,6 +283,11 @@ const std::vector<Effects::CFBO*>& CEffect::getFbos () const
     return this->m_fbos;
 }
 
+bool CEffect::isVisible () const
+{
+    return this->m_visible->processValue (this->m_object->getScene ()->getProject ()->getProperties ());
+}
+
 Effects::CFBO* CEffect::findFBO (const std::string& name)
 {
     auto cur = this->m_fbos.begin ();

+ 11 - 2
src/WallpaperEngine/Core/Objects/CEffect.h

@@ -12,10 +12,16 @@ namespace WallpaperEngine::Core
     class CObject;
 };
 
+namespace WallpaperEngine::Core::UserSettings
+{
+    class CUserSettingBoolean;
+}
+
 namespace WallpaperEngine::Core::Objects
 {
     using json = nlohmann::json;
     using namespace WallpaperEngine::Assets;
+    using namespace WallpaperEngine::Core::UserSettings;
 
     class CEffect
     {
@@ -25,14 +31,16 @@ namespace WallpaperEngine::Core::Objects
             std::string description,
             std::string group,
             std::string preview,
-            Core::CObject* object
+            Core::CObject* object,
+            CUserSettingBoolean* visible
         );
 
-        static CEffect* fromJSON (json data, Core::CObject* object, const CContainer* container);
+        static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer* container);
 
         const std::vector<std::string>& getDependencies () const;
         const std::vector<Images::CMaterial*>& getMaterials () const;
         const std::vector<Effects::CFBO*>& getFbos () const;
+        bool isVisible () const;
 
         Effects::CFBO* findFBO (const std::string& name);
     protected:
@@ -52,6 +60,7 @@ namespace WallpaperEngine::Core::Objects
         std::string m_group;
         std::string m_preview;
         Core::CObject* m_object;
+        CUserSettingBoolean* m_visible;
 
         std::vector<std::string> m_dependencies;
         std::vector<Images::CMaterial*> m_materials;

+ 8 - 3
src/WallpaperEngine/Core/Objects/CImage.cpp

@@ -2,14 +2,17 @@
 
 #include <utility>
 #include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
 
 #include "WallpaperEngine/FileSystem/FileSystem.h"
 
 using namespace WallpaperEngine::Core::Objects;
+using namespace WallpaperEngine::Core::UserSettings;
 
 CImage::CImage (
+    CScene* scene,
     Images::CMaterial* material,
-    bool visible,
+    CUserSettingBoolean* visible,
     uint32_t id,
     std::string name,
     const glm::vec3& origin,
@@ -23,7 +26,7 @@ CImage::CImage (
     uint32_t colorBlendMode,
     const glm::vec2& parallaxDepth
 ) :
-    CObject (visible, id, std::move(name), Type, origin, scale, angles),
+    CObject (scene, visible, id, std::move(name), Type, origin, scale, angles),
     m_size (size),
     m_material (material),
     m_alignment (std::move(alignment)),
@@ -36,9 +39,10 @@ CImage::CImage (
 }
 
 WallpaperEngine::Core::CObject* CImage::fromJSON (
+    CScene* scene,
     json data,
     const CContainer* container,
-    bool visible,
+    CUserSettingBoolean* visible,
     uint32_t id,
     std::string name,
     const glm::vec3& origin,
@@ -59,6 +63,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
     auto material_it = jsonFindRequired (content, "material", "Image must have a material");
 
     return new CImage (
+        scene,
         Images::CMaterial::fromFile ((*material_it).get <std::string> (), container),
         visible,
         id,

+ 12 - 3
src/WallpaperEngine/Core/Objects/CImage.h

@@ -7,20 +7,28 @@
 
 #include "WallpaperEngine/Assets/CContainer.h"
 
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
+
+namespace WallpaperEngine::Core
+{
+    class CScene;
+}
+
 namespace WallpaperEngine::Core::Objects
 {
     using json = nlohmann::json;
     using namespace WallpaperEngine::Assets;
+    using namespace WallpaperEngine::Core::UserSettings;
 
     class CImage : public CObject
     {
         friend class CObject;
-
     public:
         static CObject* fromJSON (
+            CScene* scene,
             json data,
             const CContainer* container,
-            bool visible,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             const glm::vec3& origin,
@@ -39,8 +47,9 @@ namespace WallpaperEngine::Core::Objects
 
     protected:
         CImage (
+            CScene* scene,
             Images::CMaterial* material,
-            bool visible,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             const glm::vec3& origin,

+ 7 - 1
src/WallpaperEngine/Core/Objects/CParticle.cpp

@@ -4,8 +4,10 @@
 using namespace WallpaperEngine::Core::Objects;
 
 CParticle* CParticle::fromFile (
+    CScene* scene,
     const std::string& filename,
     const CContainer* container,
+    CUserSettingBoolean* visible,
     uint32_t id,
     std::string name,
     const glm::vec3& origin,
@@ -19,8 +21,10 @@ CParticle* CParticle::fromFile (
     auto initializer_it = jsonFindRequired (data, "initializer", "Particles must have initializers");
 
     CParticle* particle = new CParticle (
+        scene,
         *starttime_it,
         *maxcount_it,
+        visible,
         id,
         name,
         origin,
@@ -64,13 +68,15 @@ CParticle* CParticle::fromFile (
 }
 
 CParticle::CParticle (
+        CScene* scene,
         uint32_t starttime,
         uint32_t maxcount,
+        CUserSettingBoolean* visible,
         uint32_t id,
         std::string name,
         const glm::vec3& origin,
         const glm::vec3& scale):
-        CObject (true, id, std::move(name), Type, origin, scale, glm::vec3 ()),
+        CObject (scene, visible, id, std::move(name), Type, origin, scale, glm::vec3 ()),
         m_starttime (starttime),
         m_maxcount (maxcount)
 {

+ 4 - 0
src/WallpaperEngine/Core/Objects/CParticle.h

@@ -17,8 +17,10 @@ namespace WallpaperEngine::Core::Objects
 
     public:
         static CParticle* fromFile (
+                CScene* scene,
                 const std::string& filename,
                 const CContainer* container,
+                CUserSettingBoolean* visible,
                 uint32_t id,
                 std::string name,
                 const glm::vec3& origin,
@@ -31,8 +33,10 @@ namespace WallpaperEngine::Core::Objects
 
     protected:
         CParticle (
+            CScene* scene,
             uint32_t starttime,
             uint32_t maxcount,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             const glm::vec3& origin,

+ 6 - 3
src/WallpaperEngine/Core/Objects/CSound.cpp

@@ -4,19 +4,21 @@
 using namespace WallpaperEngine::Core::Objects;
 
 CSound::CSound (
-        bool visible,
+        CScene* scene,
+        CUserSettingBoolean* visible,
         uint32_t id,
         std::string name,
         const glm::vec3& origin,
         const glm::vec3& scale,
         const glm::vec3& angles) :
-        CObject (visible, id, std::move(name), Type, origin, scale, angles)
+        CObject (scene, visible, id, std::move(name), Type, origin, scale, angles)
 {
 }
 
 WallpaperEngine::Core::CObject* CSound::fromJSON (
+        CScene* scene,
         json data,
-        bool visible,
+        CUserSettingBoolean* visible,
         uint32_t id,
         std::string name,
         const glm::vec3& origin,
@@ -31,6 +33,7 @@ WallpaperEngine::Core::CObject* CSound::fromJSON (
     }
 
     CSound* sound = new CSound (
+        scene,
         visible,
         id,
         name,

+ 6 - 2
src/WallpaperEngine/Core/Objects/CSound.h

@@ -2,10 +2,12 @@
 
 #include "WallpaperEngine/Core/Core.h"
 #include "WallpaperEngine/Core/CObject.h"
+#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
 
 namespace WallpaperEngine::Core::Objects
 {
     using json = nlohmann::json;
+    using namespace WallpaperEngine::Core::UserSettings;
 
     class CSound : public CObject
     {
@@ -13,8 +15,9 @@ namespace WallpaperEngine::Core::Objects
 
     public:
         static CObject* fromJSON (
+            CScene* scene,
             json data,
-            bool visible,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             const glm::vec3& origin,
@@ -27,7 +30,8 @@ namespace WallpaperEngine::Core::Objects
 
     protected:
         CSound (
-            bool visible,
+            CScene* scene,
+            CUserSettingBoolean* visible,
             uint32_t id,
             std::string name,
             const glm::vec3& origin,

+ 11 - 4
src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp

@@ -1,4 +1,6 @@
 #include "CPropertyCombo.h"
+
+#include <utility>
 #include "WallpaperEngine/Core/Core.h"
 
 using namespace WallpaperEngine::Core::Projects;
@@ -11,7 +13,8 @@ CPropertyCombo* CPropertyCombo::fromJSON (json data, const std::string& name)
 
     CPropertyCombo* combo = new CPropertyCombo (
         name,
-        *text
+        *text,
+        *value
     );
 
     if (options->is_array () == false)
@@ -38,12 +41,16 @@ CPropertyCombo* CPropertyCombo::fromJSON (json data, const std::string& name)
     return combo;
 }
 
-CPropertyCombo::CPropertyCombo (const std::string& name, const std::string& text) :
-    CProperty (name, Type, text)
+CPropertyCombo::CPropertyCombo (const std::string& name, const std::string& text, std::string  defaultValue) :
+    CProperty (name, Type, text),
+    m_defaultValue (std::move(defaultValue))
 {
 }
 
-
+const std::string& CPropertyCombo::getValue () const
+{
+    return this->m_defaultValue;
+}
 
 void CPropertyCombo::addValue (std::string label, std::string value)
 {

+ 4 - 1
src/WallpaperEngine/Core/Projects/CPropertyCombo.h

@@ -18,13 +18,16 @@ namespace WallpaperEngine::Core::Projects
     public:
         static CPropertyCombo* fromJSON (json data, const std::string& name);
 
+        const std::string& getValue () const;
+
         static const std::string Type;
 
     private:
-        CPropertyCombo (const std::string& name, const std::string& text);
+        CPropertyCombo (const std::string& name, const std::string& text, std::string  defaultValue);
 
         void addValue (std::string label, std::string value);
 
         std::vector <CPropertyComboValue*> m_values;
+        std::string m_defaultValue;
     };
 };

+ 105 - 0
src/WallpaperEngine/Core/UserSettings/CUserSettingBoolean.cpp

@@ -0,0 +1,105 @@
+#include "CUserSettingBoolean.h"
+#include "WallpaperEngine/Core/Core.h"
+
+#include "WallpaperEngine/Core/Projects/CProperty.h"
+#include "WallpaperEngine/Core/Projects/CPropertyBoolean.h"
+#include "WallpaperEngine/Core/Projects/CPropertyCombo.h"
+#include "WallpaperEngine/Core/Projects/CPropertySlider.h"
+#include "WallpaperEngine/Core/Projects/CPropertyText.h"
+
+using namespace WallpaperEngine::Core;
+using namespace WallpaperEngine::Core::Projects;
+using namespace WallpaperEngine::Core::UserSettings;
+
+CUserSettingBoolean::CUserSettingBoolean (bool hasCondition, bool hasSource, bool defaultValue, std::string source, std::string expectedValue) :
+    CUserSettingValue (Type),
+    m_hasCondition (hasCondition),
+    m_hasSource(hasSource),
+    m_default(defaultValue),
+    m_source (std::move(source)),
+    m_expectedValue(std::move(expectedValue))
+{
+}
+
+CUserSettingBoolean* CUserSettingBoolean::fromJSON (nlohmann::json& data)
+{
+    bool hasCondition = false;
+    bool hasSource = false;
+    bool defaultValue = false;
+    std::string source;
+    std::string expectedValue;
+
+    if (data.is_object () == true)
+    {
+        hasSource = true;
+        auto userIt = data.find ("user");
+        defaultValue = jsonFindDefault (data, "value", false); // is this default value right?
+
+        if (userIt != data.end ())
+        {
+            if (userIt->is_string ())
+            {
+                source = *userIt;
+            }
+            else
+            {
+                hasCondition = true;
+                source = *jsonFindRequired (userIt, "name", "Name for conditional setting must be present");
+                expectedValue = *jsonFindRequired (userIt, "condition", "Condition for conditional setting must be present");
+            }
+        }
+        else
+        {
+            fprintf (stderr, "Boolean property doesn't have user member, this could mean an scripted value");
+        }
+    }
+    else
+    {
+        if (data.is_boolean () == false)
+            throw std::runtime_error ("Expected boolean value on user settings");
+
+        defaultValue = data.get<bool> ();
+    }
+
+    return new CUserSettingBoolean (hasCondition, hasSource, defaultValue, source, expectedValue);
+}
+
+CUserSettingBoolean* CUserSettingBoolean::fromScalar (bool value)
+{
+    return new CUserSettingBoolean (false, false, value, "", "");
+}
+
+bool CUserSettingBoolean::getDefaultValue ()
+{
+    return this->m_default;
+}
+
+bool CUserSettingBoolean::processValue (const std::vector<Projects::CProperty*>& properties)
+{
+    if (this->m_hasSource == false && this->m_hasCondition == false)
+        return this->getDefaultValue ();
+
+    for (auto cur : properties)
+    {
+        if (cur->getName () != this->m_source)
+            continue;
+
+        if (this->m_hasCondition == false)
+        {
+            if (cur->is <CPropertyBoolean> ())
+                return cur->as <CPropertyBoolean> ()->getValue ();
+
+            throw std::runtime_error ("Property without condition must match type (boolean)");
+        }
+
+        // TODO: properly validate this as the combos might be more than just strings?
+        if (cur->is <CPropertyCombo> ())
+            return cur->as <CPropertyCombo> ()->getValue () == this->m_expectedValue;
+
+        throw std::runtime_error ("Boolean property with condition doesn't match against combo value");
+    }
+
+    return this->m_default;
+}
+
+std::string CUserSettingBoolean::Type = "boolean";

+ 31 - 0
src/WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "CUserSettingValue.h"
+
+namespace WallpaperEngine::Core::Projects
+{
+    class CProperty;
+}
+
+namespace WallpaperEngine::Core::UserSettings
+{
+    class CUserSettingBoolean : public CUserSettingValue
+    {
+    public:
+        static CUserSettingBoolean* fromJSON (nlohmann::json& data);
+        static CUserSettingBoolean* fromScalar (bool value);
+        static std::string Type;
+
+        bool processValue (const std::vector<Projects::CProperty*>& properties);
+        bool getDefaultValue ();
+
+    private:
+        CUserSettingBoolean (bool hasCondition, bool hasSource, bool defaultValue, std::string source, std::string expectedValue);
+
+        bool m_default;
+        bool m_hasCondition;
+        bool m_hasSource;
+        std::string m_source;
+        std::string m_expectedValue;
+    };
+}

+ 10 - 0
src/WallpaperEngine/Core/UserSettings/CUserSettingValue.cpp

@@ -0,0 +1,10 @@
+#include "CUserSettingValue.h"
+
+#include <utility>
+
+using namespace WallpaperEngine::Core::UserSettings;
+
+CUserSettingValue::CUserSettingValue (std::string type) :
+    m_type (std::move(type))
+{
+}

+ 21 - 0
src/WallpaperEngine/Core/UserSettings/CUserSettingValue.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+namespace WallpaperEngine::Core::UserSettings
+{
+    class CUserSettingValue
+    {
+    public:
+        template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
+        template<class T> T* as () { assert (is <T> ()); return (T*) this; }
+
+        template<class T> bool is () { return this->m_type == T::Type; }
+
+    protected:
+        CUserSettingValue (std::string type);
+
+    private:
+        std::string m_type;
+    };
+};

+ 1 - 1
src/WallpaperEngine/Render/CScene.cpp

@@ -159,7 +159,7 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
     {
         this->m_bloomObject = this->createObject (
             WallpaperEngine::Core::CObject::fromJSON (
-                json, this->getContainer ()
+                json, this->getScene (), this->getContainer ()
             )
         );
 

+ 5 - 0
src/WallpaperEngine/Render/Objects/CEffect.cpp

@@ -66,4 +66,9 @@ void CEffect::generateFBOs ()
             )
         );
     }
+}
+
+bool CEffect::isVisible () const
+{
+    return this->m_effect->isVisible ();
 }

+ 1 - 0
src/WallpaperEngine/Render/Objects/CEffect.h

@@ -24,6 +24,7 @@ namespace WallpaperEngine::Render::Objects
         const std::vector<Effects::CMaterial*>& getMaterials () const;
 
         const CFBO* findFBO (const std::string& name) const;
+        bool isVisible () const;
 
     private:
         void generatePasses ();

+ 48 - 8
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -237,7 +237,7 @@ void CImage::setup ()
     {
         // generate the main material used to render the image
         this->m_material = new Effects::CMaterial (
-            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
+            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image, Core::UserSettings::CUserSettingBoolean::fromScalar (true))),
             this->m_image->getMaterial ()
         );
 
@@ -284,7 +284,7 @@ void CImage::setup ()
 
         // generate the main material used to render the image
         this->m_colorBlendMaterial = new Effects::CMaterial(
-            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
+            new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image, Core::UserSettings::CUserSettingBoolean::fromScalar (true))),
             material
         );
 
@@ -335,6 +335,11 @@ void CImage::setupPasses ()
     for (; cur != end; cur ++)
     {
         Effects::CPass* pass = *cur;
+
+        // do not do anything if the passes' effect is not visible
+        if (pass->getMaterial ()->getEffect ()->isVisible () == false)
+            continue;
+
         const CFBO* prevDrawTo = drawTo;
         GLuint spacePosition = (first) ? this->getCopySpacePosition () : this->getPassSpacePosition ();
         glm::mat4* projection = (first) ? &this->m_modelViewProjectionCopy : &this->m_modelViewProjectionPass;
@@ -353,13 +358,30 @@ void CImage::setupPasses ()
                 // this one throws if no fbo was found
                 drawTo = this->getScene ()->findFBO (target);
         }
-
         // determine if it's the last element in the list as this is a screen-copy-like process
-        else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
+        else
         {
-            spacePosition = this->getSceneSpacePosition ();
-            drawTo = this->getScene ()->getFBO ();
-            projection = &this->m_modelViewProjectionScreen;
+            bool isLastPass = std::next (cur) == end && this->getImage ()->isVisible () == true;
+            auto lastIt = std::next (cur);
+
+            // determine if this is the real last pass
+            for (; lastIt != end && isLastPass == false; lastIt ++)
+            {
+                Effects::CPass* lastPass = *lastIt;
+
+                if (lastPass->getMaterial ()->getEffect ()->isVisible () == true)
+                {
+                    isLastPass = false;
+                    break;
+                }
+            }
+
+            if (isLastPass == true)
+            {
+                spacePosition = this->getSceneSpacePosition ();
+                drawTo = this->getScene ()->getFBO ();
+                projection = &this->m_modelViewProjectionScreen;
+            }
         }
 
         pass->setDestination (drawTo);
@@ -424,7 +446,25 @@ void CImage::render ()
 
     for (; cur != end; cur ++)
     {
-        if (std::next (cur) == end)
+        if ((*cur)->getMaterial ()->getEffect ()->isVisible () == false)
+            continue;
+
+        bool isLastPass = std::next (cur) == end && this->getImage ()->isVisible () == true;
+        auto lastIt = std::next (cur);
+
+        // determine if this is the real last pass
+        for (; lastIt != end && isLastPass == false; lastIt ++)
+        {
+            Effects::CPass* lastPass = *lastIt;
+
+            if (lastPass->getMaterial ()->getEffect ()->isVisible () == true)
+            {
+                isLastPass = false;
+                break;
+            }
+        }
+
+        if (isLastPass == true)
             glColorMask (true, true, true, false);
 
         (*cur)->render ();