Get all properties for a specific frame
| 234 | |
| 235 | // Get all properties for a specific frame |
| 236 | Json::Value EffectBase::BasePropertiesJSON(int64_t requested_frame) const { |
| 237 | // Generate JSON properties list |
| 238 | Json::Value root; |
| 239 | root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame); |
| 240 | root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame); |
| 241 | root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame); |
| 242 | root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame); |
| 243 | root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 30 * 60 * 60 * 48, false, requested_frame); |
| 244 | root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 30 * 60 * 60 * 48, true, requested_frame); |
| 245 | |
| 246 | // Add replace_image choices (dropdown style) |
| 247 | root["apply_before_clip"] = add_property_json("Apply Before Clip Keyframes", info.apply_before_clip, "int", "", NULL, 0, 1, false, requested_frame); |
| 248 | root["apply_before_clip"]["choices"].append(add_property_choice_json("Yes", true, info.apply_before_clip)); |
| 249 | root["apply_before_clip"]["choices"].append(add_property_choice_json("No", false, info.apply_before_clip)); |
| 250 | |
| 251 | // Set the parent effect which properties this effect will inherit |
| 252 | root["parent_effect_id"] = add_property_json("Parent", 0.0, "string", info.parent_effect_id, NULL, -1, -1, false, requested_frame); |
| 253 | |
| 254 | if (info.has_video) { |
| 255 | root["mask_invert"] = add_property_json("Mask: Invert", mask_invert, "int", "", NULL, 0, 1, false, requested_frame); |
| 256 | root["mask_invert"]["choices"].append(add_property_choice_json("Yes", true, mask_invert)); |
| 257 | root["mask_invert"]["choices"].append(add_property_choice_json("No", false, mask_invert)); |
| 258 | |
| 259 | root["mask_time_mode"] = add_property_json("Mask: Time Mode", mask_time_mode, "int", "", NULL, 0, 1, false, requested_frame); |
| 260 | root["mask_time_mode"]["choices"].append(add_property_choice_json("Timeline", MASK_TIME_TIMELINE, mask_time_mode)); |
| 261 | root["mask_time_mode"]["choices"].append(add_property_choice_json("Source FPS", MASK_TIME_SOURCE_FPS, mask_time_mode)); |
| 262 | |
| 263 | root["mask_loop_mode"] = add_property_json("Mask: Loop", mask_loop_mode, "int", "", NULL, 0, 2, false, requested_frame); |
| 264 | root["mask_loop_mode"]["choices"].append(add_property_choice_json("Play Once", MASK_LOOP_PLAY_ONCE, mask_loop_mode)); |
| 265 | root["mask_loop_mode"]["choices"].append(add_property_choice_json("Repeat", MASK_LOOP_REPEAT, mask_loop_mode)); |
| 266 | root["mask_loop_mode"]["choices"].append(add_property_choice_json("Ping-Pong", MASK_LOOP_PING_PONG, mask_loop_mode)); |
| 267 | |
| 268 | if (mask_reader) |
| 269 | root["mask_reader"] = add_property_json("Mask: Source", 0.0, "reader", mask_reader->Json(), NULL, 0, 1, false, requested_frame); |
| 270 | else |
| 271 | root["mask_reader"] = add_property_json("Mask: Source", 0.0, "reader", "{}", NULL, 0, 1, false, requested_frame); |
| 272 | } |
| 273 | |
| 274 | return root; |
| 275 | } |
| 276 | |
| 277 | ReaderBase* EffectBase::CreateReaderFromJson(const Json::Value& reader_json) const { |
| 278 | if (reader_json["type"].isNull()) |