Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
- Added `doesGyroflowProjectContainStabilisationData` in Rust land.
- Fixed mistake where files were still living on my desktop.
- Created seperate entitlements file for the FxPlug4 plugin.
- Dragging and dropping a FCPXML or Media File now works.
- Added Reveal in Finder button.
  • Loading branch information
latenitefilms committed Jul 13, 2023
1 parent b69759d commit 235b370
Show file tree
Hide file tree
Showing 10 changed files with 598 additions and 183 deletions.
4 changes: 4 additions & 0 deletions Source/Frameworks/gyroflow/inc/gyroflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ uint32_t trashCache(
const char* importMediaFile(
const char* media_file_path
);

const char* doesGyroflowProjectContainStabilisationData(
const char* gyroflow_project_data
);
95 changes: 91 additions & 4 deletions Source/Frameworks/gyroflow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,68 @@ lazy_static! {
static ref MANAGER_CACHE: Mutex<LruCache<String, Arc<StabilizationManager>>> = Mutex::new(LruCache::new(std::num::NonZeroUsize::new(8).unwrap()));
}

//---------------------------------------------------------
// Does the Gyroflow Project contain Stabilisation Data?
// Returns "PASS" or "FAIL".
//---------------------------------------------------------
#[no_mangle]
pub extern "C" fn doesGyroflowProjectContainStabilisationData(
gyroflow_project_data: *const c_char,
) -> *const c_char {
//---------------------------------------------------------
// Convert the Gyroflow Project data to a `&str`:
//---------------------------------------------------------
let gyroflow_project_data_pointer = unsafe { CStr::from_ptr(gyroflow_project_data) };
let gyroflow_project_data_string = gyroflow_project_data_pointer.to_string_lossy();

let stab = StabilizationManager::default();

//---------------------------------------------------------
// Import the `gyroflow_project_data_string`:
//---------------------------------------------------------
let blocking = true;
let path = Some(std::path::PathBuf::from(&*gyroflow_project_data_string));
let cancel_flag = Arc::new(AtomicBool::new(false));
let mut is_preset = false;
match stab.import_gyroflow_data(
gyroflow_project_data_string.as_bytes(),
blocking,
path,
|_|(),
cancel_flag,
&mut is_preset
) {
Ok(_) => {
//---------------------------------------------------------
// Check if gyroflow project contains stabilization data:
//---------------------------------------------------------
let has_motion = {
let gyro = stab.gyro.read();
!gyro.file_metadata.raw_imu.is_empty() || !gyro.file_metadata.quaternions.is_empty()
};

//---------------------------------------------------------
// Return the result as a string:
//---------------------------------------------------------
let result_string = if has_motion {
"PASS"
} else {
"FAIL"
};

let result = CString::new(result_string).unwrap();
return result.into_raw()
},
Err(e) => {
// Handle the error case
log::error!("[Gyroflow Toolbox Rust] Error importing gyroflow data: {:?}", e);

let result = CString::new("FAIL").unwrap();
return result.into_raw()
},
}
}

//---------------------------------------------------------
// The "Trash Cache" function that gets triggered from
// Objective-C Land:
Expand Down Expand Up @@ -78,17 +140,42 @@ pub extern "C" fn importMediaFile(
}
}

// Load video file. For simplicity, I'm passing None as metadata. You can change it as per your need.
match stab.load_video_file(&media_file_path_string, None) {
//---------------------------------------------------------
// Prepare metadata if file has .mxf or .braw extension:
//---------------------------------------------------------
let metadata;
if media_file_path_string.to_ascii_lowercase().ends_with(".mxf") || media_file_path_string.to_ascii_lowercase().ends_with(".braw") {
/*
let mut fileMetadata = gyroflow_core::util::get_video_metadata(&media_file_path_string);
metadata = Some(VideoMetadata {
duration_s: fileMetadata.duration_s,
fps: fileMetadata.fps,
width: fileMetadata.width,
height: fileMetadata.height,
rotation: 0
});
*/
metadata = None;
} else {
metadata = None;
};

//---------------------------------------------------------
// Load video file:
//---------------------------------------------------------
match stab.load_video_file(&media_file_path_string, metadata) {
Ok(_) => {
log::info!("[Gyroflow Toolbox Rust] Video file loaded successfully");
},
Err(e) => {
log::error!("[Gyroflow Toolbox Rust] An error occured: {:?}", e);
}
}

// Export Gyroflow data

//---------------------------------------------------------
// Export Gyroflow data:
//---------------------------------------------------------
let gyroflow_data: String;
match stab.export_gyroflow_data(false, false, "{}") {
Ok(data) => {
Expand Down
14 changes: 8 additions & 6 deletions Source/Gyroflow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@
224321B529615B0C00EA591A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
224321B729615C4400EA591A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
228E9E1929517DDA00B2571E /* GyroflowConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GyroflowConstants.h; sourceTree = "<group>"; };
22BED1BF2A5D6805000562A3 /* CustomButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomButtonView.m; path = "../../../../../../Desktop/WIP Gyroflow on GitHub/GyroflowToolbox-df8de2438817be9f802629da3510916f78447d9c/Source/Gyroflow/Plugin/CustomButtonView.m"; sourceTree = "<group>"; };
22BED1C02A5D6805000562A3 /* CustomButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomButtonView.h; path = "../../../../../../Desktop/WIP Gyroflow on GitHub/GyroflowToolbox-df8de2438817be9f802629da3510916f78447d9c/Source/Gyroflow/Plugin/CustomButtonView.h"; sourceTree = "<group>"; };
22BED1C12A5D6805000562A3 /* CustomDropZoneView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomDropZoneView.h; path = "../../../../../../Desktop/WIP Gyroflow on GitHub/GyroflowToolbox-df8de2438817be9f802629da3510916f78447d9c/Source/Gyroflow/Plugin/CustomDropZoneView.h"; sourceTree = "<group>"; };
22BED1C22A5D6805000562A3 /* CustomDropZoneView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomDropZoneView.m; path = "../../../../../../Desktop/WIP Gyroflow on GitHub/GyroflowToolbox-df8de2438817be9f802629da3510916f78447d9c/Source/Gyroflow/Plugin/CustomDropZoneView.m"; sourceTree = "<group>"; };
22BED1BF2A5D6805000562A3 /* CustomButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomButtonView.m; sourceTree = "<group>"; };
22BED1C02A5D6805000562A3 /* CustomButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomButtonView.h; sourceTree = "<group>"; };
22BED1C12A5D6805000562A3 /* CustomDropZoneView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomDropZoneView.h; sourceTree = "<group>"; };
22BED1C22A5D6805000562A3 /* CustomDropZoneView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomDropZoneView.m; sourceTree = "<group>"; };
22DAC75E2953B1A7001F2E06 /* GyroflowDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = GyroflowDocument.icns; sourceTree = "<group>"; };
22E4989F29492E8100580F67 /* Cargo.toml */ = {isa = PBXFileReference; lastKnownFileType = text; name = Cargo.toml; path = Frameworks/gyroflow/Cargo.toml; sourceTree = SOURCE_ROOT; };
22F73D6F2A5FF9A000A6F326 /* SandboxEntitlements.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SandboxEntitlements.entitlements; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -289,6 +290,7 @@
228E9E15294E817700B2571E /* Extras */ = {
isa = PBXGroup;
children = (
22F73D6F2A5FF9A000A6F326 /* SandboxEntitlements.entitlements */,
2239AB442943F8F600028B77 /* main.m */,
2239AB462943F8F600028B77 /* Info.plist */,
2239AB472943F8F600028B77 /* InfoPlist.strings */,
Expand Down Expand Up @@ -656,7 +658,7 @@
2239AB502943F8F600028B77 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Gyroflow/Wrapper Application/SandboxEntitlements.entitlements";
CODE_SIGN_ENTITLEMENTS = Gyroflow/Plugin/SandboxEntitlements.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(HARDCODED_BUILD)";
DEVELOPMENT_TEAM = A5HDJTY9X5;
Expand All @@ -683,7 +685,7 @@
2239AB512943F8F600028B77 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Gyroflow/Wrapper Application/SandboxEntitlements.entitlements";
CODE_SIGN_ENTITLEMENTS = Gyroflow/Plugin/SandboxEntitlements.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(HARDCODED_BUILD)";
DEVELOPMENT_TEAM = A5HDJTY9X5;
Expand Down
105 changes: 63 additions & 42 deletions Source/Gyroflow/Plugin/CustomDropZoneView.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,78 +38,102 @@ - (instancetype)initWithAPIManager:(id<PROAPIAccessing>)apiManager
{
_apiManager = apiManager;

[self registerForDraggedTypes:@[kFinalCutProUTI]];
//[self registerForDraggedTypes:@[kFinalCutProUTI]];
NSArray *sortedPasteboardTypes = @[@"com.apple.finalcutpro.xml.v1-11", @"com.apple.finalcutpro.xml.v1-10", @"com.apple.finalcutpro.xml.v1-9", @"com.apple.finalcutpro.xml", kFinalCutProUTI, NSPasteboardTypeFileURL];
[self registerForDraggedTypes:sortedPasteboardTypes];

self.wantsLayer = YES;
self.layer.backgroundColor = [[NSColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0] CGColor];
self.layer.borderColor = [[NSColor grayColor] CGColor];
self.layer.borderWidth = 2.0;
self.wantsLayer = YES;
self.layer.backgroundColor = [[NSColor colorWithRed:0.11 green:0.11 blue:0.11 alpha:1.0] CGColor];
self.layer.borderColor = [[NSColor blackColor] CGColor];
self.layer.borderWidth = 1.0;

//---------------------------------------------------------
// Cache the parent plugin & button ID:
//---------------------------------------------------------
_parentPlugin = parentPlugin;
_buttonID = buttonID;

//---------------------------------------------------------
// Add the button:
//---------------------------------------------------------
/*
NSButton *button = [[NSButton alloc]initWithFrame:NSMakeRect(0, 0, buttonWidth, buttonHeight)]; // x y w h
[button setButtonType:NSButtonTypeMomentaryPushIn];
[button setBezelStyle: NSBezelStyleRounded];
button.layer.backgroundColor = [NSColor colorWithCalibratedRed:66 green:66 blue:66 alpha:1].CGColor;
button.layer.shadowColor = [NSColor blackColor].CGColor;
[button setBordered:YES];
[button setTitle:buttonTitle];
[button setTarget:self];
[button setAction:@selector(buttonPressed)];
_button = button;
[self addSubview:_button];
*/
}

return self;
}

//---------------------------------------------------------
// Awake From NIB:
//---------------------------------------------------------
- (void) awakeFromNib {
NSArray *sortedPasteboardTypes = @[@"com.apple.finalcutpro.xml.v1-10", @"com.apple.finalcutpro.xml.v1-9", @"com.apple.finalcutpro.xml"];
[self registerForDraggedTypes:sortedPasteboardTypes];

}

//---------------------------------------------------------
// Dragging Entered:
//---------------------------------------------------------
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
NSArray *sortedPasteboardTypes = @[@"com.apple.finalcutpro.xml.v1-10", @"com.apple.finalcutpro.xml.v1-9", @"com.apple.finalcutpro.xml"];

NSArray *sortedPasteboardTypes = @[@"com.apple.finalcutpro.xml.v1-11", @"com.apple.finalcutpro.xml.v1-10", @"com.apple.finalcutpro.xml.v1-9", @"com.apple.finalcutpro.xml", NSPasteboardTypeFileURL];
for (NSPasteboardType pasteboardType in sortedPasteboardTypes) {
if ( [[[sender draggingPasteboard] types] containsObject:pasteboardType] ) {
_dragIsOver = true;
[self needsDisplay];
return NSDragOperationCopy;
}
}

return NSDragOperationNone;
}

//---------------------------------------------------------
// Prepare for Drag Operation:
//---------------------------------------------------------
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender {
return YES;
}

//---------------------------------------------------------
// Perform Drag Operation:
//---------------------------------------------------------
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
NSPasteboard *pasteboard = [sender draggingPasteboard];
NSString *finalCutProData = [pasteboard stringForType:kFinalCutProUTI];

// Handle the dropped Final Cut Pro data
if (finalCutProData) {
NSLog(@"Dropped Final Cut Pro data: %@", finalCutProData);

if ([[pasteboard types] containsObject:NSPasteboardTypeFileURL]) {
NSArray *classArray = [NSArray arrayWithObject:[NSURL class]];
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSPasteboardURLReadingFileURLsOnlyKey];
NSArray *fileURLs = [pasteboard readObjectsForClasses:classArray options:options];
for (NSURL *fileURL in fileURLs) {
// Do something with fileURL
NSLog(@"[Gyroflow Toolbox Renderer] Dropped file: %@", [fileURL path]);

if ([fileURL startAccessingSecurityScopedResource]) {
NSLog(@"[Gyroflow Toolbox Renderer] SUCCESSFUL startAccessingSecurityScopedResource");
} else {
NSLog(@"[Gyroflow Toolbox Renderer] FAILED to startAccessingSecurityScopedResource");
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
[_parentPlugin importDroppedMedia:fileURL];
#pragma clang diagnostic pop

return YES;
}

} else {
NSArray *sortedPasteboardTypes = @[@"com.apple.finalcutpro.xml.v1-11", @"com.apple.finalcutpro.xml.v1-10", @"com.apple.finalcutpro.xml.v1-9", @"com.apple.finalcutpro.xml"];
for (NSPasteboardType pasteboardType in sortedPasteboardTypes) {
if ( [[pasteboard types] containsObject:pasteboardType] ) {
//---------------------------------------------------------
// Trigger Dropped FCPXML Method:
//---------------------------------------------------------
NSData *data = [pasteboard dataForType:pasteboardType];
NSString *finalCutProData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

//NSLog(@"[Gyroflow Toolbox Renderer] Dropped Final Cut Pro data: %@", finalCutProData);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
[_parentPlugin importDroppedClip:finalCutProData];
#pragma clang diagnostic pop

_dragIsOver = false;
[self needsDisplay];

return YES;
}
}
}

return YES;
}

Expand Down Expand Up @@ -147,8 +171,6 @@ - (void)drawRect:(NSRect)dirtyRect {
[NSGraphicsContext restoreGraphicsState];
}



//---------------------------------------------------------
// Because custom views are hosted in an overlay window,
// the first click on them will normally just make the
Expand All @@ -163,4 +185,3 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)event
}

@end

2 changes: 2 additions & 0 deletions Source/Gyroflow/Plugin/GyroflowConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ enum {
kCB_ImportMediaFile = 35,
kCB_LoadedGyroflowProject = 40,
kCB_ReloadGyroflowProject = 50,

kCB_RevealInFinder = 55,

kCB_GyroflowProjectPath = 60,
kCB_GyroflowProjectBookmarkData = 70,
Expand Down
1 change: 1 addition & 0 deletions Source/Gyroflow/Plugin/GyroflowPlugIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
NSView* reloadGyroflowProjectView;
NSView* loadLastGyroflowProjectView;
NSView* dropZoneView;
NSView* revealInFinderView;
}
@property (assign) id<PROAPIAccessing> apiManager;
@end
Loading

0 comments on commit 235b370

Please sign in to comment.