1 /** 2 * @file 3 * @brief Source file for EffectBase class 4 * @author Jonathan Thomas <jonathan@openshot.org> 5 * 6 * @ref License 7 */ 8 9 /* LICENSE 10 * 11 * Copyright (c) 2008-2019 OpenShot Studios, LLC 12 * <http://www.openshotstudios.com/>. This file is part of 13 * OpenShot Library (libopenshot), an open-source project dedicated to 14 * delivering high quality video editing and animation solutions to the 15 * world. For more information visit <http://www.openshot.org/>. 16 * 17 * OpenShot Library (libopenshot) is free software: you can redistribute it 18 * and/or modify it under the terms of the GNU Lesser General Public License 19 * as published by the Free Software Foundation, either version 3 of the 20 * License, or (at your option) any later version. 21 * 22 * OpenShot Library (libopenshot) is distributed in the hope that it will be 23 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU Lesser General Public License for more details. 26 * 27 * You should have received a copy of the GNU Lesser General Public License 28 * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>. 29 */ 30 31 #include "EffectBase.h" 32 33 #include "Exceptions.h" 34 #include "Timeline.h" 35 36 using namespace openshot; 37 38 // Initialize the values of the EffectInfo struct InitEffectInfo()39void EffectBase::InitEffectInfo() 40 { 41 // Init clip settings 42 Position(0.0); 43 Layer(0); 44 Start(0.0); 45 End(0.0); 46 Order(0); 47 ParentClip(NULL); 48 49 parentEffect = NULL; 50 51 info.has_video = false; 52 info.has_audio = false; 53 info.has_tracked_object = false; 54 info.name = ""; 55 info.description = ""; 56 info.parent_effect_id = ""; 57 } 58 59 // Display file information DisplayInfo()60void EffectBase::DisplayInfo() { 61 std::cout << std::fixed << std::setprecision(2) << std::boolalpha; 62 std::cout << "----------------------------" << std::endl; 63 std::cout << "----- Effect Information -----" << std::endl; 64 std::cout << "----------------------------" << std::endl; 65 std::cout << "--> Name: " << info.name << std::endl; 66 std::cout << "--> Description: " << info.description << std::endl; 67 std::cout << "--> Has Video: " << info.has_video << std::endl; 68 std::cout << "--> Has Audio: " << info.has_audio << std::endl; 69 std::cout << "----------------------------" << std::endl; 70 } 71 72 // Constrain a color value from 0 to 255 constrain(int color_value)73int EffectBase::constrain(int color_value) 74 { 75 // Constrain new color from 0 to 255 76 if (color_value < 0) 77 color_value = 0; 78 else if (color_value > 255) 79 color_value = 255; 80 81 return color_value; 82 } 83 84 // Generate JSON string of this object Json() const85std::string EffectBase::Json() const { 86 87 // Return formatted string 88 return JsonValue().toStyledString(); 89 } 90 91 // Generate Json::Value for this object JsonValue() const92Json::Value EffectBase::JsonValue() const { 93 94 // Create root json object 95 Json::Value root = ClipBase::JsonValue(); // get parent properties 96 root["name"] = info.name; 97 root["class_name"] = info.class_name; 98 root["description"] = info.description; 99 root["parent_effect_id"] = info.parent_effect_id; 100 root["has_video"] = info.has_video; 101 root["has_audio"] = info.has_audio; 102 root["has_tracked_object"] = info.has_tracked_object; 103 root["order"] = Order(); 104 105 // return JsonValue 106 return root; 107 } 108 109 // Load JSON string into this object SetJson(const std::string value)110void EffectBase::SetJson(const std::string value) { 111 112 // Parse JSON string into JSON objects 113 try 114 { 115 Json::Value root = openshot::stringToJson(value); 116 // Set all values that match 117 SetJsonValue(root); 118 } 119 catch (const std::exception& e) 120 { 121 // Error parsing JSON (or missing keys) 122 throw InvalidJSON("JSON is invalid (missing keys or invalid data types)"); 123 } 124 } 125 126 // Load Json::Value into this object SetJsonValue(const Json::Value root)127void EffectBase::SetJsonValue(const Json::Value root) { 128 129 if (ParentTimeline()){ 130 // Get parent timeline 131 Timeline* parentTimeline = (Timeline *) ParentTimeline(); 132 133 // Get the list of effects on the timeline 134 std::list<EffectBase*> effects = parentTimeline->ClipEffects(); 135 136 // TODO: Fix recursive call for Object Detection 137 138 // // Loop through the effects and check if we have a child effect linked to this effect 139 for (auto const& effect : effects){ 140 // Set the properties of all effects which parentEffect points to this 141 if ((effect->info.parent_effect_id == this->Id()) && (effect->Id() != this->Id())) 142 effect->SetJsonValue(root); 143 } 144 } 145 146 // Set this effect properties with the parent effect properties (except the id and parent_effect_id) 147 Json::Value my_root; 148 if (parentEffect){ 149 my_root = parentEffect->JsonValue(); 150 my_root["id"] = this->Id(); 151 my_root["parent_effect_id"] = this->info.parent_effect_id; 152 } else { 153 my_root = root; 154 } 155 156 // Set parent data 157 ClipBase::SetJsonValue(my_root); 158 159 // Set data from Json (if key is found) 160 if (!my_root["order"].isNull()) 161 Order(my_root["order"].asInt()); 162 163 if (!my_root["parent_effect_id"].isNull()){ 164 info.parent_effect_id = my_root["parent_effect_id"].asString(); 165 if (info.parent_effect_id.size() > 0 && info.parent_effect_id != "" && parentEffect == NULL) 166 SetParentEffect(info.parent_effect_id); 167 else 168 parentEffect = NULL; 169 } 170 } 171 172 // Generate Json::Value for this object JsonInfo() const173Json::Value EffectBase::JsonInfo() const { 174 175 // Create root json object 176 Json::Value root; 177 root["name"] = info.name; 178 root["class_name"] = info.class_name; 179 root["description"] = info.description; 180 root["has_video"] = info.has_video; 181 root["has_audio"] = info.has_audio; 182 183 // return JsonValue 184 return root; 185 } 186 187 /// Parent clip object of this reader (which can be unparented and NULL) ParentClip()188openshot::ClipBase* EffectBase::ParentClip() { 189 return clip; 190 } 191 192 /// Set parent clip object of this reader ParentClip(openshot::ClipBase * new_clip)193void EffectBase::ParentClip(openshot::ClipBase* new_clip) { 194 clip = new_clip; 195 } 196 197 // Set the parent effect from which this properties will be set to SetParentEffect(std::string parentEffect_id)198void EffectBase::SetParentEffect(std::string parentEffect_id) { 199 200 // Get parent Timeline 201 Timeline* parentTimeline = (Timeline *) ParentTimeline(); 202 203 if (parentTimeline){ 204 205 // Get a pointer to the parentEffect 206 EffectBase* parentEffectPtr = parentTimeline->GetClipEffect(parentEffect_id); 207 208 if (parentEffectPtr){ 209 // Set the parent Effect 210 parentEffect = parentEffectPtr; 211 212 // Set the properties of this effect with the parent effect's properties 213 Json::Value EffectJSON = parentEffect->JsonValue(); 214 EffectJSON["id"] = this->Id(); 215 EffectJSON["parent_effect_id"] = this->info.parent_effect_id; 216 this->SetJsonValue(EffectJSON); 217 } 218 } 219 return; 220 } 221 222 // Return the ID of this effect's parent clip ParentClipId() const223std::string EffectBase::ParentClipId() const{ 224 if(clip) 225 return clip->Id(); 226 else 227 return ""; 228 } 229