Skip to content

Commit

Permalink
Expose NSArrayController to javascript.
Browse files Browse the repository at this point in the history
This should Fix #1 (Searching in the playlist).
This bindings bridge is still a bit hacky and will need further iteration before it is right.
  • Loading branch information
pdherbemont committed Dec 26, 2009
1 parent 9e58e83 commit d67227e
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 29 deletions.
6 changes: 6 additions & 0 deletions Lunettes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
635D112C104A846400D34A87 /* PreferencesWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 635D112B104A846400D34A87 /* PreferencesWindow.xib */; };
635D112E104A847300D34A87 /* PlaylistDebugWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 635D112D104A847300D34A87 /* PlaylistDebugWindow.xib */; };
635D1176104A8A8B00D34A87 /* SplashScreenWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 635D1175104A8A8400D34A87 /* SplashScreenWindow.xib */; };
635D933110E4FE9E001C8091 /* VLCArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 635D933010E4FE9E001C8091 /* VLCArrayController.m */; };
635F0F7B10CC63DC006EC30E /* VLCValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = 635F0F7A10CC63DC006EC30E /* VLCValueTransformers.m */; };
635F109310CC7E29006EC30E /* VLCPlayedProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 635F109210CC7E29006EC30E /* VLCPlayedProgressIndicator.m */; };
635F15E010CDB4D8006EC30E /* GPLWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 635F15DF10CDB4D8006EC30E /* GPLWindow.xib */; };
Expand Down Expand Up @@ -413,6 +414,8 @@
635D1125104A846000D34A87 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/OpenURLWindow.xib; sourceTree = "<group>"; };
635D1126104A846000D34A87 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/PreferencesWindow.xib; sourceTree = "<group>"; };
635D112D104A847300D34A87 /* PlaylistDebugWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = PlaylistDebugWindow.xib; path = Resources/PlaylistDebugWindow.xib; sourceTree = "<group>"; };
635D932F10E4FE9E001C8091 /* VLCArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCArrayController.h; path = Sources/VLCArrayController.h; sourceTree = "<group>"; };
635D933010E4FE9E001C8091 /* VLCArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCArrayController.m; path = Sources/VLCArrayController.m; sourceTree = "<group>"; };
635F0F7910CC63DC006EC30E /* VLCValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCValueTransformers.h; path = Sources/VLCValueTransformers.h; sourceTree = "<group>"; };
635F0F7A10CC63DC006EC30E /* VLCValueTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCValueTransformers.m; path = Sources/VLCValueTransformers.m; sourceTree = "<group>"; };
635F109110CC7E29006EC30E /* VLCPlayedProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCPlayedProgressIndicator.h; path = Sources/VLCPlayedProgressIndicator.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -948,6 +951,8 @@
635F109210CC7E29006EC30E /* VLCPlayedProgressIndicator.m */,
63F163E110D2941C003B99BE /* VLCPathWatcher.h */,
63F163E210D2941C003B99BE /* VLCPathWatcher.m */,
635D932F10E4FE9E001C8091 /* VLCArrayController.h */,
635D933010E4FE9E001C8091 /* VLCArrayController.m */,
);
name = "System Framework Addition";
sourceTree = "<group>";
Expand Down Expand Up @@ -1306,6 +1311,7 @@
635F109310CC7E29006EC30E /* VLCPlayedProgressIndicator.m in Sources */,
63F163E310D2941C003B99BE /* VLCPathWatcher.m in Sources */,
CCC6B97510DD9C130087884B /* VLCPreferencesKeys.m in Sources */,
635D933110E4FE9E001C8091 /* VLCArrayController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
17 changes: 9 additions & 8 deletions Resources/English.lproj/SplashScreenWindow.xib
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="151"/>
<integer value="159"/>
<integer value="2"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
Expand Down Expand Up @@ -303,7 +303,7 @@
<bytes key="NSWhite">MSAwAA</bytes>
</object>
<object class="NSCursor" key="NSCursor">
<string key="NSHotSpot">{1, -1}</string>
<string key="NSHotSpot">{4, 4}</string>
<int key="NSCursorType">0</int>
</object>
<int key="NScvFlags">2</int>
Expand Down Expand Up @@ -511,7 +511,7 @@
<string key="NSMinGridSize">{0, 0}</string>
<string key="NSMaxGridSize">{0, 0}</string>
<int key="NSMaxNumberOfGridRows">0</int>
<int key="NSMaxNumberOfGridColumns">0</int>
<int key="NSMaxNumberOfGridColumns">1</int>
<object class="NSArray" key="NSBackgroundColors">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSColor">
Expand Down Expand Up @@ -546,7 +546,7 @@
<object class="NSScroller" id="605763174">
<reference key="NSNextResponder" ref="218344851"/>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 144}, {233, 15}}</string>
<string key="NSFrame">{{-100, -100}, {233, 15}}</string>
<reference key="NSSuperview" ref="218344851"/>
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="218344851"/>
Expand All @@ -557,10 +557,11 @@
<string key="NSFrame">{{36, 45}, {316, 258}}</string>
<reference key="NSSuperview" ref="1006"/>
<reference key="NSNextKeyView" ref="63870782"/>
<int key="NSsFlags">562</int>
<int key="NSsFlags">530</int>
<reference key="NSVScroller" ref="380912487"/>
<reference key="NSHScroller" ref="605763174"/>
<reference key="NSContentView" ref="63870782"/>
<bytes key="NSScrollAmts">AAAAAEEgAAAAAAAAQSAAAA</bytes>
</object>
</object>
<string key="NSFrameSize">{703, 405}</string>
Expand Down Expand Up @@ -758,7 +759,7 @@
</object>
<object class="NSView" id="310541180">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<int key="NSvFlags">258</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSBox" id="286411161">
Expand Down Expand Up @@ -856,7 +857,7 @@
</object>
<object class="NSButton" id="517333551">
<reference key="NSNextResponder" ref="604917786"/>
<int key="NSvFlags">268</int>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{292, 36}, {22, 19}}</string>
<reference key="NSSuperview" ref="604917786"/>
<bool key="NSEnabled">YES</bool>
Expand All @@ -880,7 +881,7 @@
</object>
<object class="NSSlider" id="191929386">
<reference key="NSNextResponder" ref="604917786"/>
<int key="NSvFlags">268</int>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{80, 40}, {208, 12}}</string>
<reference key="NSSuperview" ref="604917786"/>
<bool key="NSEnabled">YES</bool>
Expand Down
26 changes: 25 additions & 1 deletion Resources/Style/Base/CocoaObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ KVCArrayObserver.prototype.removeAllInsertedCocoaObjects = function() {};
*/
var CocoaObject = function() {};

CocoaObject.documentCocoaObject = function()
{
return window.PlatformView.viewBackendObject(new CocoaObject);
}

/**
* This function is used by the backend to create a new
* CocoaObject.
*/
CocoaObject.prototype.clone = function () { return new CocoaObject; };

/**
* @param {string} keyPath
* @param {Object} object
Expand Down Expand Up @@ -80,4 +91,17 @@ CocoaObject.prototype.removeObserver = function (observer, keyPath)
{
window.console.assert(observer);
window.PlatformView.unobserve(observer, this, keyPath);
}
}

/**
* This functions creates in the backend an NSArrayController, and store
* it in the returned CocoaObject.
* It is bound to the keyPath property of the called CocoaObject.
*
* @param {string} keyPath to observe
* @return {CocoaObject} a CocoaObject that points to an arrayController
*/
CocoaObject.prototype.createArrayControllerFromKeyPath = function (keyPath)
{
return window.PlatformView.createArrayControllerFromBackendObjectWithKeyPath(this, keyPath);
}
23 changes: 17 additions & 6 deletions Resources/Style/Base/MediaListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,23 @@ MediaListView.prototype = {

observe: function()
{
if (this.cocoaObject)
this.cocoaObject.addObserver(this, "subitems.media");
else
{
// FIXME: Better abstraction?
window.PlatformView.addObserverForCocoaObjectWithKeyPath(this, null, "rootMediaList.media");
console.assert(!this.arrayController);
if (this.arrayController)
return;

var cocoaObject = this.cocoaObject;
if (!cocoaObject) {
// This one is certainly a hack for the root object.
// We should try to rationalize this.
cocoaObject = CocoaObject.documentCocoaObject();
this.arrayController = cocoaObject.createArrayControllerFromKeyPath("rootMediaList.media");
}
else
this.arrayController = cocoaObject.createArrayControllerFromKeyPath("subitems.media");

this.arrayController.addObserver(this, "arrangedObjects");

var search = document.getElementById("search-playlist");
this.arrayController.bindToObjectProperty("searchString", search, "value");
}
}
2 changes: 1 addition & 1 deletion Resources/Style/Base/Utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Element.prototype.detach = function ()

Element.prototype.bindKey = function (property, toKeyPath)
{
window.PlatformView.bindPropertyTo(this, property, toKeyPath);
window.PlatformView.bindDOMObjectToCocoaObject(this, property, CocoaObject.documentCocoaObject(), toKeyPath);
}

/******************************************************************************
Expand Down
2 changes: 1 addition & 1 deletion Resources/Style/Default/PlaylistController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var PlaylistController = function()
PlaylistController.prototype = {
init: function()
{
window.PlatformView.bindPropertyTo(this, "rootMediaListCount", "rootMediaList.media.@count");
window.PlatformView.bindDOMObjectToCocoaObject(this, "rootMediaListCount", CocoaObject.documentCocoaObject(), "rootMediaList.media.@count");
},

_rootMediaListCount: 0,
Expand Down
4 changes: 2 additions & 2 deletions Resources/Style/Default/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ input[type=search] {

.resize {
position: absolute;
height: 32px;
width: 32px;
height: 16px;
width: 16px;
display: block;
bottom: 0px;
right: 0px;
Expand Down
2 changes: 1 addition & 1 deletion Resources/Style/Default/hud.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<div id="title" class="title">Movie title</div>
<div class="timeinfo">
<div class="ellapsed-time">--:--</div>
<input id="timeline" type="range" class="timeline" max="1000" value="0">
<input id="timeline" type="range" class="timeline" max="1000">
<div class="remaining-time">--:--</div>
</div>
<button class="leave-fullscreen"></button>
Expand Down
2 changes: 1 addition & 1 deletion Resources/Style/Default/video-window.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</div>

</div>
<div class="controls"><input type="search" class="search" placeholder="Search" value=""></div>
<div class="controls"><input type="search" id="search-playlist" class="search" placeholder="Search" value="" incremental="true"></div>
<div class="resize resize-platform-window"></div>
</div>

Expand Down
17 changes: 17 additions & 0 deletions Sources/VLCArrayController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// VLCArrayController.h
// Lunettes
//
// Created by Pierre d'Herbemont on 12/24/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface VLCArrayController : NSArrayController {
NSString *_searchString;
}

@property (readwrite, retain) NSString *searchString;
@end
47 changes: 47 additions & 0 deletions Sources/VLCArrayController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// VLCArrayController.m
// Lunettes
//
// Created by Pierre d'Herbemont on 12/24/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "VLCArrayController.h"


@implementation VLCArrayController
- (id)init
{
self = [super init];
if (!self)
return nil;
_searchString = [@"" retain];
return self;
}

- (void)dealloc
{
[_searchString release];
[super dealloc];
}

- (NSString *)searchString
{
return _searchString;
}

- (void)setSearchString:(NSString *)string
{
// This method is a hack for now.
// We should only pass the predicate string, and make
// no assumption of the content.
NSPredicate *predicate;
if ([string isEqualToString:@""])
predicate = [NSPredicate predicateWithValue:YES];
else
predicate = [NSPredicate predicateWithFormat:@"metaDictionary.title CONTAINS[cd] %@", string];
[self setFilterPredicate:predicate];
[_searchString release];
_searchString = [string copy];
}
@end
11 changes: 11 additions & 0 deletions Sources/VLCStyledVideoWindow.m
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ - (void)setAlphaValue:(CGFloat)alpha
}
#endif

#pragma mark -
#pragma mark Zoom

/**
* We have to reimplement zooming, because it seems to be broken with borderless window
*/
- (void)zoom:(id)sender
{
NSRect frame = [[self screen] frame];
[self setFrame:frame display:YES animate:YES];
}
#pragma mark -
#pragma mark Javascript bindings
/* Javascript bindings: We are not necessarily respecting Cocoa naming scheme convention. That's an exception */
Expand Down
35 changes: 27 additions & 8 deletions Sources/VLCStyledVideoWindowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#import "VLCMediaDocument.h"
#import "DOMElement_Additions.h"
#import "DOMHTMLElement_Additions.h"
#import "VLCArrayController.h"

@interface VLCStyledVideoWindowView ()
- (void)videoDidResize;
Expand Down Expand Up @@ -328,11 +329,6 @@ - (NSUInteger)count
return [[self rootMediaList] count];
}

- (void)bindDOMObject:(DOMObject *)domObject property:(NSString *)property toKeyPath:(NSString *)keyPath
{
[_bindings bindDOMObject:domObject property:property toObject:self withKeyPath:keyPath];
}

- (void)bindDOMObject:(DOMNode *)domObject property:(NSString *)property toBackendObject:(WebScriptObject *)object withKeyPath:(NSString *)keyPath
{
[_bindings bindDOMObject:domObject property:property toObject:[object valueForKey:@"backendObject"] withKeyPath:keyPath];
Expand All @@ -345,14 +341,31 @@ - (void)unbindDOMObject:(DOMNode *)domObject property:(NSString *)property

- (void)addObserver:(WebScriptObject *)observer forCocoaObject:(WebScriptObject *)object withKeyPath:(NSString *)keyPath
{
[_bindings observe:object ? [object valueForKey:@"backendObject"] : self withKeyPath:keyPath observer:observer];
[_bindings observe:[object valueForKey:@"backendObject"] withKeyPath:keyPath observer:observer];
}

- (void)playCocoaObject:(WebScriptObject *)object
{
[[self mediaListPlayer] playMedia:[object valueForKey:@"backendObject"]];
}

- (WebScriptObject *)createArrayControllerFromBackendObject:(WebScriptObject *)object withKeyPath:(NSString *)keyPath
{
id backendObject = [object valueForKey:@"backendObject"];
NSArrayController *controller = [[VLCArrayController alloc] init];
[controller bind:@"contentArray" toObject:backendObject withKeyPath:keyPath options:nil];
WebScriptObject *ret = [object callWebScriptMethod:@"clone" withArguments:nil];
[ret setValue:controller forKey:@"backendObject"];
[controller release];
return ret;
}

- (WebScriptObject *)viewBackendObject:(WebScriptObject *)object
{
[object setValue:self forKey:@"backendObject"];
return object;
}


+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
{
Expand All @@ -370,8 +383,6 @@ + (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
return NO;
if (sel == @selector(setPosition:))
return NO;
if (sel == @selector(bindDOMObject:property:toKeyPath:))
return NO;
if (sel == @selector(addObserver:forCocoaObject:withKeyPath:))
return NO;
if (sel == @selector(bindDOMObject:property:toBackendObject:withKeyPath:))
Expand All @@ -380,6 +391,10 @@ + (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
return NO;
if (sel == @selector(playCocoaObject:))
return NO;
if (sel == @selector(createArrayControllerFromBackendObject:withKeyPath:))
return NO;
if (sel == @selector(viewBackendObject:))
return NO;

return YES;
}
Expand All @@ -396,6 +411,10 @@ + (NSString *)webScriptNameForSelector:(SEL)sel
return @"unbindDOMObject";
if (sel == @selector(playCocoaObject:))
return @"playCocoaObject";
if (sel == @selector(createArrayControllerFromBackendObject:withKeyPath:))
return @"createArrayControllerFromBackendObjectWithKeyPath";
if (sel == @selector(viewBackendObject:))
return @"viewBackendObject";
return nil;
}

Expand Down

0 comments on commit d67227e

Please sign in to comment.