Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: MacRuby/MacRuby
...
head fork: MacRuby/MacRuby
Checking mergeability… Don’t worry, you can still create the pull request.
  • 5 commits
  • 34 files changed
  • 0 commit comments
  • 2 contributors
Commits on Apr 29, 2010
Laurent Sansonetti branching for 0.6
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/0.6@3978 23306eb0-4c56-4727-a40e-e92c0eb68959
b148ef4
Commits on Apr 30, 2010
Thibault Martin-Lagardette HotCocoa style > MacRuby style
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/0.6@3980 23306eb0-4c56-4727-a40e-e92c0eb68959
662ca05
Commits on May 03, 2010
Thibault Martin-Lagardette Add Skreenics sample to the 0.6 branch
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/0.6@4002 23306eb0-4c56-4727-a40e-e92c0eb68959
9891f85
Thibault Martin-Lagardette Also update "About MacRuby Examples" to includes Skreenics
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/0.6@4003 23306eb0-4c56-4727-a40e-e92c0eb68959
0834d42
Laurent Sansonetti backport r4004, r4005, r4006 from trunk
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/0.6@4007 23306eb0-4c56-4727-a40e-e92c0eb68959
b790eef
Showing with 8,317 additions and 47 deletions.
  1. +70 −26 NSArray.m
  2. +40 −10 NSDictionary.m
  3. +29 −4 NSString.m
  4. +1 −1  bridgesupport.cpp
  5. +8 −1 sample-macruby/About MacRuby Examples.rtf
  6. BIN  sample-macruby/Skreenics/English.lproj/InfoPlist.strings
  7. +6,096 −0 sample-macruby/Skreenics/English.lproj/MainMenu.xib
  8. BIN  sample-macruby/Skreenics/Images/Skreenics.icns
  9. BIN  sample-macruby/Skreenics/Images/ToolbarRemoveTemplate.png
  10. +32 −0 sample-macruby/Skreenics/Info.plist
  11. +33 −0 sample-macruby/Skreenics/README.txt
  12. +592 −0 sample-macruby/Skreenics/Skreenics.xcodeproj/project.pbxproj
  13. +1 −0  sample-macruby/Skreenics/Tests/run_suite.rb
  14. +17 −0 sample-macruby/Skreenics/Tests/stub_test.rb
  15. +57 −0 sample-macruby/Skreenics/UserDefaults.plist
  16. +14 −0 sample-macruby/Skreenics/main.m
  17. +24 −0 sample-macruby/Skreenics/rb_main.rb
  18. +65 −0 sample-macruby/Skreenics/src/Additions/NSStringAdditions.rb
  19. +93 −0 sample-macruby/Skreenics/src/Controllers/SKPreferencesController.rb
  20. +63 −0 sample-macruby/Skreenics/src/GUI/SKDragView.rb
  21. +152 −0 sample-macruby/Skreenics/src/GUI/SKProgressCell.rb
  22. +141 −0 sample-macruby/Skreenics/src/GUI/SKProgressIndicator.rb
  23. +247 −0 sample-macruby/Skreenics/src/Operations/SKGenerateThumbnailOperation.rb
  24. +38 −0 sample-macruby/Skreenics/src/SKConstants.rb
  25. +134 −0 sample-macruby/Skreenics/src/SKVideoItem.rb
  26. +222 −0 sample-macruby/Skreenics/src/SkreenicsAppDelegate.rb
  27. +56 −0 sample-macruby/Skreenics/src/Value Transformers/ExpandedPathToIconTransformer.rb
  28. +45 −0 sample-macruby/Skreenics/src/Value Transformers/ExpandedPathToPathTransformer.rb
  29. +43 −0 sample-macruby/Skreenics/src/Value Transformers/SKRgbToNSColorTransformer.rb
  30. +2 −2 sample-macruby/ViewModelDemo/Superview.rb
  31. +0 −1  spec/macruby/tags/macruby/core/array_tags.txt
  32. +0 −1  spec/macruby/tags/macruby/core/hash_tags.txt
  33. +0 −1  spec/macruby/tags/macruby/core/string_tags.txt
  34. +2 −0  vm.cpp
View
96 NSArray.m
@@ -18,6 +18,27 @@
VALUE rb_cNSArray;
VALUE rb_cNSMutableArray;
+// Some NSArray instances actually do not even respond to mutable methods.
+// So one way to know is to check if the addObject: method exists.
+#define CHECK_MUTABLE(obj) \
+ do { \
+ if (![obj respondsToSelector:@selector(addObject:)]) { \
+ rb_raise(rb_eRuntimeError, \
+ "can't modify frozen/immutable array"); \
+ } \
+ } \
+ while (0)
+
+// If a given mutable operation raises an NSException error,
+// it is likely that the object is not mutable.
+#define TRY_MOP(code) \
+ @try { \
+ code; \
+ } \
+ @catch(NSException *exc) { \
+ rb_raise(rb_eRuntimeError, "can't modify frozen/immutable array"); \
+ }
+
static id
nsary_dup(id rcv, SEL sel)
{
@@ -41,7 +62,8 @@
static id
nsary_clear(id rcv, SEL sel)
{
- [rcv removeAllObjects];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv removeAllObjects]);
return rcv;
}
@@ -159,21 +181,23 @@
rlen = RARRAY_LEN(rpl);
}
+ CHECK_MUTABLE(ary);
+
if (beg >= n) {
for (long i = n; i < beg; i++) {
- [ary addObject:[NSNull null]];
+ TRY_MOP([ary addObject:[NSNull null]]);
}
if (rlen > 0 && rpl != Qundef) {
- [ary addObjectsFromArray:(id)rpl];
+ TRY_MOP([ary addObjectsFromArray:(id)rpl]);
}
}
else {
if (rlen > 0 && rpl != Qundef) {
- [ary replaceObjectsInRange:NSMakeRange(beg, len)
- withObjectsFromArray:(id)rpl];
+ TRY_MOP([ary replaceObjectsInRange:NSMakeRange(beg, len)
+ withObjectsFromArray:(id)rpl]);
}
else {
- [ary removeObjectsInRange:NSMakeRange(beg, len)];
+ TRY_MOP([ary removeObjectsInRange:NSMakeRange(beg, len)]);
}
}
}
@@ -189,12 +213,15 @@
idx - len);
}
}
+
+ CHECK_MUTABLE(ary);
+
if (len <= idx) {
for (long i = len; i <= idx; i++) {
- [ary addObject:[NSNull null]];
+ TRY_MOP([ary addObject:[NSNull null]]);
}
}
- [ary replaceObjectAtIndex:idx withObject:RB2OC(val)];
+ TRY_MOP([ary replaceObjectAtIndex:idx withObject:RB2OC(val)]);
}
static VALUE
@@ -286,8 +313,9 @@
}
if (remove) {
+ CHECK_MUTABLE(ary);
for (long i = 0; i < n; i++) {
- [ary removeObjectAtIndex:offset];
+ TRY_MOP([ary removeObjectAtIndex:offset]);
}
}
@@ -318,14 +346,16 @@
nsary_concat(id rcv, SEL sel, VALUE ary)
{
ary = to_ary(ary);
- [rcv addObjectsFromArray:(id)ary];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv addObjectsFromArray:(id)ary]);
return rcv;
}
static id
nsary_push(id rcv, SEL sel, VALUE elem)
{
- [rcv addObject:RB2OC(elem)];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv addObject:RB2OC(elem)]);
return rcv;
}
@@ -341,11 +371,12 @@
static VALUE
nsary_pop(id rcv, SEL sel, int argc, VALUE *argv)
{
+ CHECK_MUTABLE(rcv);
if (argc == 0) {
const long len = [rcv count];
if (len > 0) {
id elem = [rcv objectAtIndex:len - 1];
- [rcv removeObjectAtIndex:len - 1];
+ TRY_MOP([rcv removeObjectAtIndex:len - 1]);
return OC2RB(elem);
}
return Qnil;
@@ -356,11 +387,12 @@
static VALUE
nsary_shift(id rcv, SEL sel, int argc, VALUE *argv)
{
+ CHECK_MUTABLE(rcv);
if (argc == 0) {
const long len = [rcv count];
if (len > 0) {
id elem = [rcv objectAtIndex:0];
- [rcv removeObjectAtIndex:0];
+ TRY_MOP([rcv removeObjectAtIndex:0]);
return OC2RB(elem);
}
return Qnil;
@@ -371,8 +403,9 @@
static id
nsary_unshift(id rcv, SEL sel, int argc, VALUE *argv)
{
+ CHECK_MUTABLE(rcv);
for (int i = argc - 1; i >= 0; i--) {
- [rcv insertObject:RB2OC(argv[i]) atIndex:0];
+ TRY_MOP([rcv insertObject:RB2OC(argv[i]) atIndex:0]);
}
return rcv;
}
@@ -380,6 +413,7 @@
static void
nsary_insert(id rcv, long idx, VALUE elem)
{
+ CHECK_MUTABLE(rcv);
const long len = [rcv count];
if (idx < 0) {
idx += len;
@@ -389,15 +423,16 @@
}
if (idx > len) {
for (long i = len; i < idx; i++) {
- [rcv addObject:[NSNull null]];
+ TRY_MOP([rcv addObject:[NSNull null]]);
}
}
- [rcv insertObject:RB2OC(elem) atIndex:idx];
+ TRY_MOP([rcv insertObject:RB2OC(elem) atIndex:idx]);
}
static id
nsary_insert_m(id rcv, SEL sel, int argc, VALUE *argv)
{
+ CHECK_MUTABLE(rcv);
if (argc < 1) {
rb_raise(rb_eArgError, "wrong number of arguments (at least 1)");
}
@@ -539,8 +574,9 @@
static id
nsary_reverse_bang(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
for (long i = 0, count = [rcv count]; i < (count / 2); i++) {
- [rcv exchangeObjectAtIndex:i withObjectAtIndex:count - i - 1];
+ TRY_MOP([rcv exchangeObjectAtIndex:i withObjectAtIndex:count - i - 1]);
}
return rcv;
}
@@ -563,12 +599,13 @@
static id
nsary_sort_bang(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
if ([rcv count] > 1) {
if (rb_block_given_p()) {
- [rcv sortUsingFunction:sort_block context:NULL];
+ TRY_MOP([rcv sortUsingFunction:sort_block context:NULL]);
}
else {
- [rcv sortUsingSelector:@selector(compare:)];
+ TRY_MOP([rcv sortUsingSelector:@selector(compare:)]);
}
}
return rcv;
@@ -583,11 +620,12 @@
static VALUE
collect(id rcv)
{
+ CHECK_MUTABLE(rcv);
for (long i = 0, count = [rcv count]; i < count; i++) {
id elem = [rcv objectAtIndex:i];
id newval = RB2OC(rb_yield(OC2RB(elem)));
RETURN_IF_BROKEN();
- [rcv replaceObjectAtIndex:i withObject:newval];
+ TRY_MOP([rcv replaceObjectAtIndex:i withObject:newval]);
}
return (VALUE)rcv;
}
@@ -653,8 +691,9 @@
NSRange range = NSMakeRange(0, len);
NSUInteger index;
bool changed = false;
+ CHECK_MUTABLE(rcv);
while ((index = [rcv indexOfObject:ocelem inRange:range]) != NSNotFound) {
- [rcv removeObjectAtIndex:index];
+ TRY_MOP([rcv removeObjectAtIndex:index]);
range.location = index;
range.length = --len - index;
changed = true;
@@ -677,6 +716,7 @@
static VALUE
nsary_delete_at(id rcv, SEL sel, VALUE pos)
{
+ CHECK_MUTABLE(rcv);
long index = NUM2LONG(pos);
const long len = [rcv count];
if (index >= len) {
@@ -689,20 +729,21 @@
}
}
VALUE elem = OC2RB([rcv objectAtIndex:index]);
- [rcv removeObjectAtIndex:index];
+ TRY_MOP([rcv removeObjectAtIndex:index]);
return elem;
}
static VALUE
reject(id rcv)
{
+ CHECK_MUTABLE(rcv);
bool changed = false;
for (long i = 0, n = [rcv count]; i < n; i++) {
VALUE elem = OC2RB([rcv objectAtIndex:i]);
VALUE test = rb_yield(elem);
RETURN_IF_BROKEN();
if (RTEST(test)) {
- [rcv removeObjectAtIndex:i];
+ TRY_MOP([rcv removeObjectAtIndex:i]);
n--;
i--;
changed = true;
@@ -736,7 +777,8 @@
nsary_replace(id rcv, SEL sel, VALUE other)
{
other = to_ary(other);
- [rcv setArray:(id)other];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv setArray:(id)other]);
return rcv;
}
@@ -828,6 +870,7 @@
static VALUE
nsary_uniq_bang(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
long len = [rcv count];
bool changed = false;
for (long i = 0; i < len; i++) {
@@ -835,7 +878,7 @@
NSRange range = NSMakeRange(i + 1, len - i - 1);
NSUInteger index;
while ((index = [rcv indexOfObject:elem inRange:range]) != NSNotFound) {
- [rcv removeObjectAtIndex:index];
+ TRY_MOP([rcv removeObjectAtIndex:index]);
range.location = index;
range.length = --len - index;
changed = true;
@@ -919,10 +962,11 @@
static id
nsary_shuffle_bang(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
long i = [rcv count];
while (i > 0) {
const long j = rb_genrand_real() * i--;
- [rcv exchangeObjectAtIndex:i withObjectAtIndex:j];
+ TRY_MOP([rcv exchangeObjectAtIndex:i withObjectAtIndex:j]);
}
return rcv;
}
View
50 NSDictionary.m
@@ -18,6 +18,27 @@
VALUE rb_cNSHash;
VALUE rb_cNSMutableHash;
+// Some NSDictionary instances actually do not even respond to mutable methods.
+// So one way to know is to check if the setObject:forKey: method exists.
+#define CHECK_MUTABLE(obj) \
+ do { \
+ if (![obj respondsToSelector:@selector(setObject:forKey:)]) { \
+ rb_raise(rb_eRuntimeError, \
+ "can't modify frozen/immutable hash"); \
+ } \
+ } \
+ while (0)
+
+// If a given mutable operation raises an NSException error,
+// it is likely that the object is not mutable.
+#define TRY_MOP(code) \
+ @try { \
+ code; \
+ } \
+ @catch(NSException *exc) { \
+ rb_raise(rb_eRuntimeError, "can't modify frozen/immutable hash"); \
+ }
+
static id
to_hash(id hash)
{
@@ -47,12 +68,14 @@
static id
nshash_rehash(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
NSArray *keys = [rcv allKeys];
NSArray *values = [rcv allValues];
assert([keys count] == [values count]);
- [rcv removeAllObjects];
+ TRY_MOP([rcv removeAllObjects]);
for (unsigned i = 0, count = [keys count]; i < count; i++) {
- [rcv setObject:[values objectAtIndex:i] forKey:[keys objectAtIndex:i]];
+ TRY_MOP([rcv setObject:[values objectAtIndex:i]
+ forKey:[keys objectAtIndex:i]]);
}
return rcv;
}
@@ -113,7 +136,8 @@
static VALUE
nshash_aset(id rcv, SEL sel, VALUE key, VALUE val)
{
- [rcv setObject:RB2OC(val) forKey:RB2OC(key)];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv setObject:RB2OC(val) forKey:RB2OC(key)]);
return val;
}
@@ -251,11 +275,12 @@
static VALUE
nshash_shift(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
if ([rcv count] > 0) {
id key = [[rcv keyEnumerator] nextObject];
assert(key != NULL);
id value = [rcv objectForKey:key];
- [rcv removeObjectForKey:key];
+ TRY_MOP([rcv removeObjectForKey:key]);
return rb_assoc_new(OC2RB(key), OC2RB(value));
}
return nshash_default(rcv, 0, 0, NULL);
@@ -264,10 +289,11 @@
static VALUE
nshash_delete(id rcv, SEL sel, VALUE key)
{
+ CHECK_MUTABLE(rcv);
id ockey = RB2OC(key);
id value = [rcv objectForKey:ockey];
if (value != nil) {
- [rcv removeObjectForKey:ockey];
+ TRY_MOP([rcv removeObjectForKey:ockey]);
return OC2RB(value);
}
if (rb_block_given_p()) {
@@ -279,6 +305,7 @@
static VALUE
nshash_delete_if(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
RETURN_ENUMERATOR(rcv, 0, 0);
NSMutableArray *ary = [NSMutableArray new];
for (id key in rcv) {
@@ -288,19 +315,20 @@
}
RETURN_IF_BROKEN();
}
- [rcv removeObjectsForKeys:ary];
+ TRY_MOP([rcv removeObjectsForKeys:ary]);
return (VALUE)rcv;
}
static VALUE
nshash_select(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
RETURN_ENUMERATOR(rcv, 0, 0);
NSMutableDictionary *dict = [NSMutableDictionary new];
for (id key in rcv) {
id value = [rcv objectForKey:key];
if (RTEST(rb_yield_values(2, OC2RB(key), OC2RB(value)))) {
- [dict setObject:value forKey:key];
+ TRY_MOP([dict setObject:value forKey:key]);
}
RETURN_IF_BROKEN();
}
@@ -334,6 +362,7 @@
nshash_update(id rcv, SEL sel, id hash)
{
hash = to_hash(hash);
+ CHECK_MUTABLE(rcv);
if (rb_block_given_p()) {
for (id key in hash) {
id value = [hash objectForKey:key];
@@ -342,13 +371,13 @@
value = RB2OC(rb_yield_values(3, OC2RB(key), OC2RB(old_value),
OC2RB(value)));
}
- [rcv setObject:value forKey:key];
+ TRY_MOP([rcv setObject:value forKey:key]);
}
}
else {
for (id key in hash) {
id value = [hash objectForKey:key];
- [rcv setObject:value forKey:key];
+ TRY_MOP([rcv setObject:value forKey:key]);
}
}
return rcv;
@@ -364,7 +393,8 @@
nshash_replace(id rcv, SEL sel, id hash)
{
hash = to_hash(hash);
- [rcv setDictionary:hash];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv setDictionary:hash]);
return rcv;
}
View
33 NSString.m
@@ -18,6 +18,27 @@
VALUE rb_cNSString;
VALUE rb_cNSMutableString;
+// Some NSString instances actually do not even respond to mutable methods.
+// So one way to know is to check if the setString: method exists.
+#define CHECK_MUTABLE(obj) \
+ do { \
+ if (![obj respondsToSelector:@selector(setString:)]) { \
+ rb_raise(rb_eRuntimeError, \
+ "can't modify frozen/immutable string"); \
+ } \
+ } \
+ while (0)
+
+// If a given mutable operation raises an NSException error,
+// it is likely that the object is not mutable.
+#define TRY_MOP(code) \
+ @try { \
+ code; \
+ } \
+ @catch(NSException *exc) { \
+ rb_raise(rb_eRuntimeError, "can't modify frozen/immutable string"); \
+ }
+
static inline VALUE
to_str(VALUE str)
{
@@ -59,16 +80,18 @@
static id
nsstr_replace(id rcv, SEL sel, VALUE other)
{
- [rcv setString:(id)to_str(other)];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv setString:(id)to_str(other)]);
return rcv;
}
static id
nsstr_clear(id rcv, SEL sel)
{
+ CHECK_MUTABLE(rcv);
const long len = [rcv length];
if (len > 0) {
- [rcv deleteCharactersInRange:NSMakeRange(0, len)];
+ TRY_MOP([rcv deleteCharactersInRange:NSMakeRange(0, len)]);
}
return rcv;
}
@@ -95,7 +118,8 @@
static id
nsstr_concat(id rcv, SEL sel, VALUE other)
{
- [rcv appendString:(id)to_str(other)];
+ CHECK_MUTABLE(rcv);
+ TRY_MOP([rcv appendString:(id)to_str(other)]);
return rcv;
}
@@ -180,10 +204,11 @@
static VALUE
nsstr_forward_bang(id rcv, SEL sel, int argc, VALUE *argv)
{
+ CHECK_MUTABLE(rcv);
VALUE rcv_rstr = nsstr_to_rstr(rcv);
VALUE ret = rb_vm_call_with_cache2(rb_vm_get_call_cache(sel),
rb_vm_current_block(), rcv_rstr, 0, sel, argc, argv);
- [rcv setString:(id)rcv_rstr];
+ TRY_MOP([rcv setString:(id)rcv_rstr]);
return ret;
}
View
2  bridgesupport.cpp
@@ -560,7 +560,7 @@ RoxorCore::register_anonymous_bs_struct(const char *type)
field->name = (char *)"?";
field->type = strdup(s_types.at(i).c_str());
}
- bs_struct->opaque = true;
+ bs_struct->opaque = false;
// Prepare the boxed structure.
rb_vm_bs_boxed_t *boxed = (rb_vm_bs_boxed_t *)
View
9 sample-macruby/About MacRuby Examples.rtf
@@ -1,4 +1,4 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf250
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf290
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 LucidaGrande;\f2\froman\fcharset0 Times-Roman;
\f3\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;}
@@ -72,6 +72,13 @@ OutlineView
\b0 Custom-shaped NSWindow with transparent window content.\
\
+\b Skreenics
+\b0 QTKit, NSOperation, NSUserDefaults,\
+ NSValueTransformer, Drag and drop,\
+ Key-Value coding/observing,\
+ custom views / cells.\
+\
+
\b ViewModelDemo
\b0 NSView, NSTimer\
\
View
BIN  sample-macruby/Skreenics/English.lproj/InfoPlist.strings
Binary file not shown
View
6,096 sample-macruby/Skreenics/English.lproj/MainMenu.xib
6,096 additions, 0 deletions not shown
View
BIN  sample-macruby/Skreenics/Images/Skreenics.icns
Binary file not shown
View
BIN  sample-macruby/Skreenics/Images/ToolbarRemoveTemplate.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
32 sample-macruby/Skreenics/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>Skreenics.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>net.neelyx.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0.1</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0.1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>10.6</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
View
33 sample-macruby/Skreenics/README.txt
@@ -0,0 +1,33 @@
+== Skreenics ==
+
+This is a MacRuby port of the original Objective-C Skreenics application,
+available at http://code.google.com/p/skreenics/
+
+Both the original application and MacRuby port were written by the same
+author: Thibault Martin-Lagardette.
+
+Special thanks to "Hadley Rouse"
+(Redditor licenseplate <redditorlicenseplate [at] gmail [dot] com>)
+for the great icon!
+
+== Licensing ==
+
+Copyright (c) 2009-2010 Thibault Martin-Lagardette
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
592 sample-macruby/Skreenics/Skreenics.xcodeproj/project.pbxproj
@@ -0,0 +1,592 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 44;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 172754BD107597F200D0347B /* Unit Tests */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 172754C7107597F400D0347B /* Build configuration list for PBXAggregateTarget "Unit Tests" */;
+ buildPhases = (
+ 172754BC107597F200D0347B /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = "Unit Tests";
+ productName = "Unit Tests";
+ };
+ 4D1A51A110A4FF5D0046A98A /* Compile */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 4D1A51AB10A4FF6A0046A98A /* Build configuration list for PBXAggregateTarget "Compile" */;
+ buildPhases = (
+ 4D1A51A010A4FF5D0046A98A /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = Compile;
+ productName = Compile;
+ };
+ 4D1A51A510A4FF640046A98A /* Embed */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 4D1A51AC10A4FF6A0046A98A /* Build configuration list for PBXAggregateTarget "Embed" */;
+ buildPhases = (
+ 4D1A51A410A4FF640046A98A /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = Embed;
+ productName = Embed;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 2BFA9DA710CDF852007972A1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2BFA9DA510CDF852007972A1 /* MainMenu.xib */; };
+ 4DE339F70D74FCDD00ADB6EE /* rb_main.rb in Resources */ = {isa = PBXBuildFile; fileRef = 4DE339F60D74FCDD00ADB6EE /* rb_main.rb */; };
+ 4DE3BE140D8651D900ECA448 /* MacRuby.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DE3BE130D8651D900ECA448 /* MacRuby.framework */; };
+ 766A5A751187FA920097145F /* SkreenicsAppDelegate.rb in Resources */ = {isa = PBXBuildFile; fileRef = 766A5A741187FA920097145F /* SkreenicsAppDelegate.rb */; };
+ 766A5AF41188B7B90097145F /* SKVideoItem.rb in Resources */ = {isa = PBXBuildFile; fileRef = 766A5AF31188B7B90097145F /* SKVideoItem.rb */; };
+ 768F163D1188BE0F00F5B792 /* SKPreferencesController.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F163C1188BE0F00F5B792 /* SKPreferencesController.rb */; };
+ 768F16441188C4B500F5B792 /* SKGenerateThumbnailOperation.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F16431188C4B500F5B792 /* SKGenerateThumbnailOperation.rb */; };
+ 768F1654118A168700F5B792 /* SKDragView.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F1651118A168700F5B792 /* SKDragView.rb */; };
+ 768F1655118A168700F5B792 /* SKProgressCell.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F1652118A168700F5B792 /* SKProgressCell.rb */; };
+ 768F1656118A168700F5B792 /* SKProgressIndicator.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F1653118A168700F5B792 /* SKProgressIndicator.rb */; };
+ 768F1664118A16BF00F5B792 /* NSStringAdditions.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F1663118A16BF00F5B792 /* NSStringAdditions.rb */; };
+ 768F166A118A18E700F5B792 /* SKRgbToNSColorTransformer.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F1669118A18E700F5B792 /* SKRgbToNSColorTransformer.rb */; };
+ 768F166C118A1DBE00F5B792 /* ExpandedPathToPathTransformer.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F166B118A1DBE00F5B792 /* ExpandedPathToPathTransformer.rb */; };
+ 768F166E118A1E4A00F5B792 /* ExpandedPathToIconTransformer.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F166D118A1E4A00F5B792 /* ExpandedPathToIconTransformer.rb */; };
+ 768F1670118A1F3500F5B792 /* SKConstants.rb in Resources */ = {isa = PBXBuildFile; fileRef = 768F166F118A1F3500F5B792 /* SKConstants.rb */; };
+ 768F1696118A215E00F5B792 /* UserDefaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 768F1695118A215E00F5B792 /* UserDefaults.plist */; };
+ 768F16AF118A21C200F5B792 /* Skreenics.icns in Resources */ = {isa = PBXBuildFile; fileRef = 768F16AD118A21C200F5B792 /* Skreenics.icns */; };
+ 768F16B0118A21C200F5B792 /* ToolbarRemoveTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = 768F16AE118A21C200F5B792 /* ToolbarRemoveTemplate.png */; };
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 172754B4107597CF00D0347B /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ 172754D5107598EA00D0347B /* stub_test.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = stub_test.rb; sourceTree = "<group>"; };
+ 17D55CD81076A1A2008207BD /* run_suite.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = run_suite.rb; sourceTree = "<group>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 2BFA9DA610CDF852007972A1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ 4DE339F60D74FCDD00ADB6EE /* rb_main.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = rb_main.rb; sourceTree = "<group>"; };
+ 4DE3BE130D8651D900ECA448 /* MacRuby.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MacRuby.framework; path = /Library/Frameworks/MacRuby.framework; sourceTree = "<absolute>"; };
+ 766A5A741187FA920097145F /* SkreenicsAppDelegate.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SkreenicsAppDelegate.rb; sourceTree = "<group>"; };
+ 766A5AF31188B7B90097145F /* SKVideoItem.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKVideoItem.rb; sourceTree = "<group>"; };
+ 768F163C1188BE0F00F5B792 /* SKPreferencesController.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKPreferencesController.rb; sourceTree = "<group>"; };
+ 768F16431188C4B500F5B792 /* SKGenerateThumbnailOperation.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKGenerateThumbnailOperation.rb; sourceTree = "<group>"; };
+ 768F1651118A168700F5B792 /* SKDragView.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKDragView.rb; sourceTree = "<group>"; };
+ 768F1652118A168700F5B792 /* SKProgressCell.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKProgressCell.rb; sourceTree = "<group>"; };
+ 768F1653118A168700F5B792 /* SKProgressIndicator.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKProgressIndicator.rb; sourceTree = "<group>"; };
+ 768F1663118A16BF00F5B792 /* NSStringAdditions.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = NSStringAdditions.rb; sourceTree = "<group>"; };
+ 768F1669118A18E700F5B792 /* SKRgbToNSColorTransformer.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKRgbToNSColorTransformer.rb; sourceTree = "<group>"; };
+ 768F166B118A1DBE00F5B792 /* ExpandedPathToPathTransformer.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = ExpandedPathToPathTransformer.rb; sourceTree = "<group>"; };
+ 768F166D118A1E4A00F5B792 /* ExpandedPathToIconTransformer.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = ExpandedPathToIconTransformer.rb; sourceTree = "<group>"; };
+ 768F166F118A1F3500F5B792 /* SKConstants.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = SKConstants.rb; sourceTree = "<group>"; };
+ 768F1695118A215E00F5B792 /* UserDefaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = UserDefaults.plist; sourceTree = "<group>"; };
+ 768F16AD118A21C200F5B792 /* Skreenics.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Skreenics.icns; sourceTree = "<group>"; };
+ 768F16AE118A21C200F5B792 /* ToolbarRemoveTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ToolbarRemoveTemplate.png; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* Skreenics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Skreenics.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ 4DE3BE140D8651D900ECA448 /* MacRuby.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ 766A5A741187FA920097145F /* SkreenicsAppDelegate.rb */,
+ 766A5AF31188B7B90097145F /* SKVideoItem.rb */,
+ 768F166F118A1F3500F5B792 /* SKConstants.rb */,
+ 768F163B1188BDEB00F5B792 /* Controllers */,
+ 768F16421188C4A100F5B792 /* Operations */,
+ 768F16451188DDE500F5B792 /* GUI */,
+ 768F1657118A169C00F5B792 /* Additions */,
+ 768F1665118A18BA00F5B792 /* Value Transformers */,
+ );
+ name = Source;
+ path = src;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 4DE3BE130D8651D900ECA448 /* MacRuby.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 172754AE1075979200D0347B /* Tests */ = {
+ isa = PBXGroup;
+ children = (
+ 172754D5107598EA00D0347B /* stub_test.rb */,
+ 17D55CD81076A1A2008207BD /* run_suite.rb */,
+ );
+ path = Tests;
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* Skreenics.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* Skreenics */ = {
+ isa = PBXGroup;
+ children = (
+ 172754AE1075979200D0347B /* Tests */,
+ 080E96DDFE201D6D7F000001 /* Source */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = Skreenics;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 4DE339F60D74FCDD00ADB6EE /* rb_main.rb */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 768F16A2118A21A100F5B792 /* Images */,
+ 768F1695118A215E00F5B792 /* UserDefaults.plist */,
+ 2BFA9DA510CDF852007972A1 /* MainMenu.xib */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 768F163B1188BDEB00F5B792 /* Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 768F163C1188BE0F00F5B792 /* SKPreferencesController.rb */,
+ );
+ path = Controllers;
+ sourceTree = "<group>";
+ };
+ 768F16421188C4A100F5B792 /* Operations */ = {
+ isa = PBXGroup;
+ children = (
+ 768F16431188C4B500F5B792 /* SKGenerateThumbnailOperation.rb */,
+ );
+ path = Operations;
+ sourceTree = "<group>";
+ };
+ 768F16451188DDE500F5B792 /* GUI */ = {
+ isa = PBXGroup;
+ children = (
+ 768F1652118A168700F5B792 /* SKProgressCell.rb */,
+ 768F1653118A168700F5B792 /* SKProgressIndicator.rb */,
+ 768F1651118A168700F5B792 /* SKDragView.rb */,
+ );
+ path = GUI;
+ sourceTree = "<group>";
+ };
+ 768F1657118A169C00F5B792 /* Additions */ = {
+ isa = PBXGroup;
+ children = (
+ 768F1663118A16BF00F5B792 /* NSStringAdditions.rb */,
+ );
+ path = Additions;
+ sourceTree = "<group>";
+ };
+ 768F1665118A18BA00F5B792 /* Value Transformers */ = {
+ isa = PBXGroup;
+ children = (
+ 768F1669118A18E700F5B792 /* SKRgbToNSColorTransformer.rb */,
+ 768F166B118A1DBE00F5B792 /* ExpandedPathToPathTransformer.rb */,
+ 768F166D118A1E4A00F5B792 /* ExpandedPathToIconTransformer.rb */,
+ );
+ path = "Value Transformers";
+ sourceTree = "<group>";
+ };
+ 768F16A2118A21A100F5B792 /* Images */ = {
+ isa = PBXGroup;
+ children = (
+ 768F16AD118A21C200F5B792 /* Skreenics.icns */,
+ 768F16AE118A21C200F5B792 /* ToolbarRemoveTemplate.png */,
+ );
+ path = Images;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D1107260486CEB800E47090 /* Skreenics */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Skreenics" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ 172754B4107597CF00D0347B /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Skreenics;
+ productInstallPath = "$(HOME)/Applications";
+ productName = Skreenics;
+ productReference = 8D1107320486CEB800E47090 /* Skreenics.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Skreenics" */;
+ compatibilityVersion = "Xcode 3.0";
+ hasScannedForEncodings = 1;
+ mainGroup = 29B97314FDCFA39411CA2CEA /* Skreenics */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D1107260486CEB800E47090 /* Skreenics */,
+ 172754BD107597F200D0347B /* Unit Tests */,
+ 4D1A51A110A4FF5D0046A98A /* Compile */,
+ 4D1A51A510A4FF640046A98A /* Embed */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ 4DE339F70D74FCDD00ADB6EE /* rb_main.rb in Resources */,
+ 2BFA9DA710CDF852007972A1 /* MainMenu.xib in Resources */,
+ 766A5A751187FA920097145F /* SkreenicsAppDelegate.rb in Resources */,
+ 766A5AF41188B7B90097145F /* SKVideoItem.rb in Resources */,
+ 768F163D1188BE0F00F5B792 /* SKPreferencesController.rb in Resources */,
+ 768F16441188C4B500F5B792 /* SKGenerateThumbnailOperation.rb in Resources */,
+ 768F1654118A168700F5B792 /* SKDragView.rb in Resources */,
+ 768F1655118A168700F5B792 /* SKProgressCell.rb in Resources */,
+ 768F1656118A168700F5B792 /* SKProgressIndicator.rb in Resources */,
+ 768F1664118A16BF00F5B792 /* NSStringAdditions.rb in Resources */,
+ 768F166A118A18E700F5B792 /* SKRgbToNSColorTransformer.rb in Resources */,
+ 768F166C118A1DBE00F5B792 /* ExpandedPathToPathTransformer.rb in Resources */,
+ 768F166E118A1E4A00F5B792 /* ExpandedPathToIconTransformer.rb in Resources */,
+ 768F1670118A1F3500F5B792 /* SKConstants.rb in Resources */,
+ 768F1696118A215E00F5B792 /* UserDefaults.plist in Resources */,
+ 768F16AF118A21C200F5B792 /* Skreenics.icns in Resources */,
+ 768F16B0118A21C200F5B792 /* ToolbarRemoveTemplate.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 172754BC107597F200D0347B /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/usr/local/bin/macruby Tests/run_suite.rb";
+ };
+ 4D1A51A010A4FF5D0046A98A /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# The macruby_deploy command-line tool with the --compile argument will compile every Ruby source file of your .app into machine code. Default options will be used. Pass the -h option to get more information.\nPATH=\"$PATH:/usr/local/bin\" macruby_deploy --compile \"$TARGET_BUILD_DIR/$PROJECT_NAME.app\"";
+ };
+ 4D1A51A410A4FF640046A98A /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# The macruby_deploy command-line tool with the --embed argument will make sure the MacRuby framework will be embedded in your .app. Default options will be used. Pass the -h option to get more information.\nPATH=\"$PATH:/usr/local/bin\" macruby_deploy --embed \"$TARGET_BUILD_DIR/$PROJECT_NAME.app\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072D0486CEB800E47090 /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ 2BFA9DA510CDF852007972A1 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2BFA9DA610CDF852007972A1 /* English */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 172754BE107597F200D0347B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = "Unit Tests";
+ };
+ name = Debug;
+ };
+ 172754BF107597F200D0347B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = "Unit Tests";
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 4D1A51A210A4FF5D0046A98A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = Compile;
+ };
+ name = Debug;
+ };
+ 4D1A51A310A4FF5D0046A98A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = Compile;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 4D1A51A610A4FF640046A98A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = Embed;
+ };
+ name = Debug;
+ };
+ 4D1A51A710A4FF640046A98A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = Embed;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/build/Debug\"",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = Skreenics;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/build/Debug\"",
+ );
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = Skreenics;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(NATIVE_ARCH_ACTUAL)";
+ GCC_ENABLE_OBJC_GC = required;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(NATIVE_ARCH_ACTUAL)";
+ GCC_ENABLE_OBJC_GC = required;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 172754C7107597F400D0347B /* Build configuration list for PBXAggregateTarget "Unit Tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 172754BE107597F200D0347B /* Debug */,
+ 172754BF107597F200D0347B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4D1A51AB10A4FF6A0046A98A /* Build configuration list for PBXAggregateTarget "Compile" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4D1A51A210A4FF5D0046A98A /* Debug */,
+ 4D1A51A310A4FF5D0046A98A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4D1A51AC10A4FF6A0046A98A /* Build configuration list for PBXAggregateTarget "Embed" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4D1A51A610A4FF640046A98A /* Debug */,
+ 4D1A51A710A4FF640046A98A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Skreenics" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Skreenics" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
View
1  sample-macruby/Skreenics/Tests/run_suite.rb
@@ -0,0 +1 @@
+Dir.glob(File.expand_path('../**/*_test.rb', __FILE__)).each { |test| require test }
View
17 sample-macruby/Skreenics/Tests/stub_test.rb
@@ -0,0 +1,17 @@
+require 'test/unit'
+
+#require 'ruby_file_to_test'
+
+class SimpleTest < Test::Unit::TestCase
+ def setup
+ puts 'setup called'
+ end
+
+ def teardown
+ puts 'teardown called'
+ end
+
+ def test_fail
+ assert false, 'Assertion was false.'
+ end
+end
View
57 sample-macruby/Skreenics/UserDefaults.plist
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>SKOuputFolder</key>
+ <string>~/Desktop</string>
+ <key>SKPreferMovieFileFolder</key>
+ <false/>
+ <key>SKAddSubfoldersOnDrop</key>
+ <false/>
+ <key>SKImageFormatPrefKey</key>
+ <string>PNG</string>
+ <key>SKMaximumConcurrentOperations</key>
+ <integer>4</integer>
+ <key>SKImageFileWidth</key>
+ <integer>1024</integer>
+ <key>SKSpacingBetweenThumbnails</key>
+ <integer>10</integer>
+ <key>SKNumberOfRows</key>
+ <integer>5</integer>
+ <key>SKNumberOfColumns</key>
+ <integer>3</integer>
+ <key>SKImageBackgroundColor</key>
+ <dict>
+ <key>Red</key>
+ <integer>1</integer>
+ <key>Green</key>
+ <integer>1</integer>
+ <key>Blue</key>
+ <integer>1</integer>
+ <key>Alpha</key>
+ <integer>1</integer>
+ </dict>
+ <key>SKImageShadowColor</key>
+ <dict>
+ <key>Red</key>
+ <real>0.495</real>
+ <key>Green</key>
+ <real>0.495</real>
+ <key>Blue</key>
+ <real>0.495</real>
+ <key>Alpha</key>
+ <real>0.95</real>
+ </dict>
+ <key>SKImageMovieInfoColor</key>
+ <dict>
+ <key>Red</key>
+ <integer>0</integer>
+ <key>Green</key>
+ <integer>0</integer>
+ <key>Blue</key>
+ <integer>0</integer>
+ <key>Alpha</key>
+ <integer>1</integer>
+ </dict>
+</dict>
+</plist>
View
14 sample-macruby/Skreenics/main.m
@@ -0,0 +1,14 @@
+//
+// main.m
+// Skreenics
+//
+// Created by naixn on 27/04/10.
+// Copyright Thibault Martin-Lagardette 2010. All rights reserved.
+//
+
+#import <MacRuby/MacRuby.h>
+
+int main(int argc, char *argv[])
+{
+ return macruby_main("rb_main.rb", argc, argv);
+}
View
24 sample-macruby/Skreenics/rb_main.rb
@@ -0,0 +1,24 @@
+#
+# rb_main.rb
+# Skreenics
+#
+# Created by naixn on 27/04/10.
+# Copyright Thibault Martin-Lagardette 2010. All rights reserved.
+#
+
+# Loading the Cocoa framework. If you need to load more frameworks, you can
+# do that here too.
+framework 'Cocoa'
+framework 'QTKit'
+
+# Loading all the Ruby project files.
+main = File.basename(__FILE__, File.extname(__FILE__))
+dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation
+Dir.glob(File.join(dir_path, '*.{rb,rbo}')).map { |x| File.basename(x, File.extname(x)) }.uniq.each do |path|
+ if path != main
+ require(path)
+ end
+end
+
+# Starting the Cocoa main loop.
+NSApplicationMain(0, nil)
View
65 sample-macruby/Skreenics/src/Additions/NSStringAdditions.rb
@@ -0,0 +1,65 @@
+=begin
+/******************************************************************************
+ * $Id: NSStringAdditions.m 9140 2009-09-18 03:49:55Z livings124 $
+ *
+ * Copyright (c) 2005-2009 Transmission authors and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+=end
+
+# NSStringAdditions.rb
+# Skreenics
+#
+# Created by naixn on 29/04/10.
+# Copyright 2010 Thibault Martin-Lagardette. All rights reserved.
+
+class NSString
+ def self.stringForFileSize(size)
+ if size < 1024
+ if size != 1
+ return "%lld bytes" % size
+ else
+ return "1 byte"
+ end
+ end
+
+ if size < (1024 ** 2)
+ convertedSize = size / 1024.0
+ unit = "KB"
+ elsif size < (1024 ** 3)
+ convertedSize = size / (1024.0 ** 2.0)
+ unit = "MB"
+ elsif size < (1024 ** 4)
+ convertedSize = size / (1024.0 ** 3.0)
+ unit = "GB"
+ else
+ convertedSize = size / (1024.0 ** 4.0)
+ unit = "TB"
+ end
+
+ # attempt to have minimum of 3 digits with at least 1 decimal
+ if convertedSize <= 9.995
+ return ("%.2f %s" % [convertedSize, unit])
+ else
+ return ("%.1f %s" % [convertedSize, unit])
+ end
+ end
+end
+
View
93 sample-macruby/Skreenics/src/Controllers/SKPreferencesController.rb
@@ -0,0 +1,93 @@
+# SKPreferencesController.rb
+# Skreenics
+#
+# Created by naixn on 28/04/10.
+# Copyright 2010 Thibault Martin-Lagardette. All rights reserved.
+
+class SKPreferencesController
+ attr_accessor :window
+ attr_accessor :menuItem_outputFolder
+ attr_accessor :menuItem_sameAsVideoFolder
+ attr_accessor :popup_downloadFolder
+ attr_accessor :fileTypes
+
+ @@availableFileTypes = [
+ {:displayName => "PNG", :extension => "png", :file_type => NSPNGFileType},
+ {:displayName => "JPEG", :extension => "jpg", :file_type => NSJPEGFileType}
+ ]
+
+ def init
+ if super
+ @fileTypes = @@availableFileTypes.map { |ftype| ftype[:displayName] }
+ self
+ end
+ end
+
+ def self.imageFileType
+ imageFormatFromPrefs = NSUserDefaults.standardUserDefaults[KSKImageFormatPrefKey]
+ ftype = @@availableFileTypes.select { |ft| ft[:displayName] == imageFormatFromPrefs }.first
+ unless ftype.nil?
+ return ftype[:file_type]
+ end
+ return NSPNGFileType
+ end
+
+ def self.imageFileExtension
+ imageFormatFromPrefs = NSUserDefaults.standardUserDefaults[KSKImageFormatPrefKey]
+ ftype = @@availableFileTypes.select { |ft| ft[:displayName] == imageFormatFromPrefs }.first
+ unless ftype.nil?
+ return ftype[:extension]
+ end
+ return "png"
+ end
+
+ #pragma mark UI
+
+ def showPreferences(sender)
+ @window.makeKeyAndOrderFront(self)
+ end
+
+ def awakeFromNib
+ selectMenuItemFromPrefs
+ end
+
+ def selectMenuItemFromPrefs
+ if NSUserDefaults.standardUserDefaults[KSKPreferMovieFileFolderPrefKey]
+ popup_downloadFolder.selectItem(menuItem_sameAsVideoFolder)
+ else
+ popup_downloadFolder.selectItem(menuItem_outputFolder)
+ end
+ end
+
+ def setSaveFolder(sender)
+ NSUserDefaults.standardUserDefaults[KSKPreferMovieFileFolderPrefKey] =
+ (popup_downloadFolder.selectedItem == menuItem_sameAsVideoFolder)
+ end
+
+ def folderSheetClosed(openPanel, returnCode:code, contextInfo:info)
+ if code == NSOKButton
+ popup_downloadFolder.selectItem(menuItem_outputFolder)
+ NSUserDefaults.standardUserDefaults[KSKOuputFolderPrefKey] = openPanel.URLs[0].path
+ setSaveFolder(self)
+ else
+ selectMenuItemFromPrefs
+ end
+ end
+
+ def openSelectOutputFolderSheet(sender)
+ panel = NSOpenPanel.openPanel
+ panel.setTitle("Select Save Folder")
+ panel.setPrompt("Select")
+ panel.setAllowsMultipleSelectio(false)
+ panel.setCanChooseFiles(false)
+ panel.setCanChooseDirectories(true)
+ panel.setCanCreateDirectories(true)
+ panel.beginSheetForDirectory(nil,
+ file: nil,
+ types: nil,
+ modalForWindow: window,
+ modalDelegate: self,
+ didEndSelector: "folderSheetClosed:returnCode:contextInfo:",
+ contextInfo: nil)
+ end
+end
View
63 sample-macruby/Skreenics/src/GUI/SKDragView.rb
@@ -0,0 +1,63 @@
+# SKDragView.rb
+# Skreenics
+#
+# Created by naixn on 29/04/10.
+# Copyright 2010 Thibault Martin-Lagardette. All rights reserved.
+
+class SKDragView < NSView
+ attr_writer :dragDelegate
+
+ def initWithCoder(coder)
+ if super
+ registerForDraggedTypes([NSFilenamesPboardType])
+ @acceptableMovieTypes = QTMovie.movieTypesWithOptions(QTIncludeCommonTypes)
+ @dragDelegate = nil
+ self
+ end
+ end
+
+ #pragma mark Drag and Drop Operations
+
+ def draggingEntered(sender)
+ # Init some variables
+ workspace = NSWorkspace.sharedWorkspace
+ filemanager = NSFileManager.defaultManager
+ pboard = sender.draggingPasteboard
+ sourceDragMask = sender.draggingSourceOperationMask
+ canQTKitInitDraggedFiles = false
+ pathIsDirectory = false
+
+ # We accept data from pasteboard only if it contains filenames
+ if pboard.types.containsObject(NSFilenamesPboardType)
+ # Look if we have at least one type of file we can deal with (movie / folder)
+ pboard.propertyListForType(NSFilenamesPboardType).each do |filePath|
+ ptr = Pointer.new_with_type('B')
+ filemanager.fileExistsAtPath(filePath, isDirectory: ptr)
+ pathIsDirectory = ptr[0]
+ break if pathIsDirectory
+ if @acceptableMovieTypes.containsObject(workspace.typeOfFile(filePath, error: nil))
+ canQTKitInitDraggedFiles = true
+ break
+ end
+ end
+ # If a folder is dragged, of the filename list contains a movie, return "NSDragOperationCopy" to get the (+) icon
+ if (pathIsDirectory or canQTKitInitDraggedFiles) and (sourceDragMask & NSDragOperationCopy)
+ return NSDragOperationCopy
+ end
+ end
+ # If all of the above failed, then we can't handle anything that was dragged
+ return NSDragOperationNone
+ end
+
+ def performDragOperation(sender)
+ pboard = sender.draggingPasteboard
+ if pboard.types.containsObject(NSFilenamesPboardType)
+ pboard.propertyListForType(NSFilenamesPboardType).each do |filePath|
+ @dragDelegate.addDragPathElement(filePath)
+ end
+ return true
+ end
+ return false
+ end
+end
+
View
152 sample-macruby/Skreenics/src/GUI/SKProgressCell.rb
@@ -0,0 +1,152 @@
+# SKProgressCell.rb
+# Skreenics
+#
+# Created by naixn on 28/04/10.
+# Copyright 2010 Thibault Martin-Lagardette. All rights reserved.
+
+VERTICAL_PADDING = 5.0
+HORIZ_PADDING = 13.0
+IMAGE_SIZE = 45.0
+FILENAME_Y_PADDING = 4.0
+PROGRESS_Y_PADDING = 22.0
+PROGSTR_Y_PADDING = 37.0
+LPADDING = (2 * HORIZ_PADDING) + IMAGE_SIZE
+NON_INFO_AREA = (3 * HORIZ_PADDING) + IMAGE_SIZE
+
+class SKProgressCell < NSCell
+
+ def initWithCoder(coder)
+ super
+ self
+ end
+
+ def copyWithZone(zone)
+ return super
+ end
+
+ #pragma mark AttributedStrings Generation
+
+ def attributedStringForFilename
+ filename = (representedObject.filename || "")
+ paragraphStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy
+ paragraphStyle.setLineBreakMode(NSLineBreakByTruncatingTail)
+ stringAttributes = {
+ NSFontAttributeName => NSFont.fontWithName("Lucida Grande", size:11.0),
+ NSForegroundColorAttributeName => NSColor.blackColor,
+ NSParagraphStyleAttributeName => paragraphStyle
+ }
+ return NSAttributedString.alloc.initWithString(filename, attributes: stringAttributes)
+ end
+
+ def attributedStringForProgress
+ progressString = (representedObject.progressString || "")
+ paragraphStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy
+ paragraphStyle.setLineBreakMode(NSLineBreakByTruncatingTail)
+ stringAttributes = {
+ NSFontAttributeName => NSFont.fontWithName("Lucida Grande", size:9.0),
+ NSForegroundColorAttributeName => NSColor.grayColor,
+ NSParagraphStyleAttributeName => paragraphStyle
+ }
+ return NSAttributedString.alloc.initWithString(progressString, attributes: stringAttributes)
+ end
+
+ #pragma mark Padding calculations
+
+ def infoAreaLeftPadding
+ LPADDING
+ end
+
+ def infoAreaWidthInBounds(bounds)
+ return NSWidth(bounds) - NON_INFO_AREA
+ end
+
+ #pragma mark Bounds calculations
+
+ def iconRectForBounds(bounds)
+ iconRect = NSMakeRect(0, 0, 0, 0)
+ iconRect.size = NSMakeSize(IMAGE_SIZE, IMAGE_SIZE)
+ iconRect.origin = bounds.origin
+ iconRect.origin.x += HORIZ_PADDING
+ iconRect.origin.y += (NSHeight(bounds) / 2) - (IMAGE_SIZE / 2)
+ return iconRect
+ end
+
+ def progressIndicRectForBounds(bounds)
+ progressIndicRect = NSMakeRect(0, 0, 0, 0)
+ progressIndicRect.size.height = NSProgressIndicatorPreferredThickness
+ progressIndicRect.size.width = infoAreaWidthInBounds(bounds)
+ progressIndicRect.origin = bounds.origin
+ progressIndicRect.origin.x = infoAreaLeftPadding
+ progressIndicRect.origin.y += PROGRESS_Y_PADDING
+ return progressIndicRect
+ end
+
+ def filenameRectForBounds(bounds, withAttributedString:filenameAttributedString)
+ filenameRect = NSMakeRect(0, 0, 0, 0)
+ filenameRect.size = filenameAttributedString.size
+ filenameRect.size.width = infoAreaWidthInBounds(bounds)
+ filenameRect.origin = bounds.origin
+ filenameRect.origin.x += infoAreaLeftPadding
+ filenameRect.origin.y += FILENAME_Y_PADDING
+ return filenameRect
+ end
+
+ def progressStringRectForBounds(bounds, withAttributedString:progressAttributedString)
+ progressStringRect = NSMakeRect(0, 0, 0, 0)
+ progressStringRect.size = progressAttributedString.size
+ progressStringRect.size.width = infoAreaWidthInBounds(bounds)
+ progressStringRect.origin = bounds.origin
+ progressStringRect.origin.x = infoAreaLeftPadding
+ progressStringRect.origin.y += PROGSTR_Y_PADDING
+ return progressStringRect
+ end
+
+ #pragma mark Draw
+
+ def drawInteriorWithFrame(frame, inView:controlView)
+ filenameAttributedString = attributedStringForFilename
+ progressAttributedString = attributedStringForProgress
+
+ # Draw the icon
+ iconRect = iconRectForBounds(frame)
+ icon = representedObject.icon
+ if not icon.nil?
+ icon.setFlipped(controlView.isFlipped)
+ icon.drawInRect(iconRect,
+ fromRect: NSZeroRect,
+ operation: NSCompositeSourceOver,
+ fraction: 1.0)
+ else
+ # If there is no icon, just draw a square
+ NSBezierPath.strokeRect(iconRect)
+ end
+
+ # Draw the filename
+ filenameRect = filenameRectForBounds(frame, withAttributedString: filenameAttributedString)
+ filename = representedObject.filename
+ if filename.length > 0
+ filenameAttributedString.drawInRect(filenameRect)
+ end
+
+ # Draw the progress indicator
+ progressIndicRect = progressIndicRectForBounds(frame)
+ progressIndicator = representedObject.progressIndicator
+ if progressIndicator
+ if progressIndicator.superview.nil?
+ controlView.addSubview(progressIndicator)
+ end
+ progressIndicator.setFrame(progressIndicRect)
+ end
+
+ # Draw the progress string
+ progressStringRect = progressStringRectForBounds(frame, withAttributedString: progressAttributedString)
+ progressString = representedObject.progressString
+ if progressString.length > 0
+ progressAttributedString.drawInRect(progressStringRect)
+ end
+
+ # Tell the view to display the changes
+ controlView.setNeedsDisplay
+ end
+end
+
View
141 sample-macruby/Skreenics/src/GUI/SKProgressIndicator.rb
@@ -0,0 +1,141 @@
+# SKProgressIndicator.rb
+# Skreenics
+#
+# Created by naixn on 29/04/10.
+# Copyright 2010 Thibault Martin-Lagardette. All rights reserved.
+
+SKProgressIndicatorPreferredThickness = 14,
+SKProgressIndicatorPreferredSmallThickness = 10,
+SKProgressIndicatorPreferredLargeThickness = 18
+KSKProgressIndicatorError = -42.0
+
+class SKProgressAnimator < NSAnimation
+ def initWithDelegate(delegate, from:from, to:to)
+ if initWithDuration(0.20, animationCurve: NSAnimationEaseInOut)
+ setDelegate(delegate)
+ setFrameRate(60.0)
+ setAnimationBlockingMode(NSAnimationNonblocking)
+ @originalProgress = from
+ @finalProgress = to
+ self
+ end
+ end
+
+ def setCurrentProgress(progress)
+ super
+
+ value = currentValue
+ if animationCurve == NSAnimationEaseOut
+ value = 1.0 - value
+ end
+ delegate.setProgressValue(@originalProgress + (@finalProgress - @originalProgress) * value)
+ end
+end
+
+class SKProgressIndicator < NSView
+ attr_accessor :maxProgressValue
+
+ def init
+ if super
+ @progressValue = 0.0
+ @maxProgressValue = 100.0
+ @progressAnimation = nil
+ self
+ end
+ end
+
+ def initWithCoder(coder)
+ if super
+ @progressValue = 0.0
+ @maxProgressValue = 100.0
+ @progressAnimation = nil
+ self
+ end
+ end
+
+ #pragma mark Progress value
+
+ def progressValue
+ return @progressValue
+ end
+
+ def setProgressValue(value)
+ if value > @maxProgressValue
+ value = @maxProgressValue
+ elsif (value < 0.0 and value != KSKProgressIndicatorError)
+ value = 0.0
+ end
+ @progressValue = value
+ setNeedsDisplay(true)
+ end
+
+ def setAnimatedProgressValue(value)
+ if value != @progressValue
+ if @progressValue != KSKProgressIndicatorError
+ if @progressAnimation
+ @progressAnimation.stopAnimation
+ @progressAnimation = nil
+ end
+ @progressAnimation = SKProgressAnimator.alloc.initWithDelegate(self, from: @progressValue, to: value)
+ @progressAnimation.startAnimation
+ else
+ setProgressValue(value)
+ end
+ end
+ end
+
+ #pragma mark Progress Indicator delegate
+
+ def animationDidEnd(animation)
+ @progressAnimation = nil
+ end
+
+ #pragma mark Draw related
+
+ @@colorComponents = {
+ :gradiantHolder => { :red => 0.85, :green => 0.85, :blue => 0.85, :alpha => 1.0 },
+ :redGradiant => { :red => 0.8, :green => 0.4, :blue => 0.4, :alpha => 1.0 },
+ :greenGradiant => { :red => 0.4, :green => 0.8, :blue => 0.4, :alpha => 1.0 },
+ :blueGradiant => { :red => 0.43, :green => 0.64, :blue => 0.93, :alpha => 1.0 }
+ }
+
+ def gradiantWithColors(c)
+ baseColor = NSColor.colorWithCalibratedRed(c[:red], green: c[:green], blue: c[:blue], alpha: c[:alpha])
+ fadedColor1 = NSColor.colorWithCalibratedRed((c[:red] * 0.90), green:(c[:green] * 0.90), blue:(c[:blue] * 0.90), alpha:(c[:alpha]))
+ fadedColor2 = NSColor.colorWithCalibratedRed((c[:red] * 0.80), green:(c[:green] * 0.80), blue:(c[:blue] * 0.80), alpha:(c[:alpha]))
+ colorList = [baseColor, baseColor, fadedColor1, fadedColor2, baseColor]
+ locations = Pointer.new('d', 5)
+ locations[0] = 0.0
+ locations[1] = 0.5
+ locations[2] = 0.8
+ locations[3] = 0.9
+ locations[4] = 1.0
+ return NSGradient.alloc.initWithColors(colorList, atLocations: locations, colorSpace: NSColorSpace.genericRGBColorSpace)
+ end
+
+ def drawRect(dirtyRect)
+ progressRect = NSMakeRect(0, 0, 0, 0)
+ gradiantWithColors(@@colorComponents[:gradiantHolder]).drawInRect(dirtyRect, angle: 90.0)
+ if not @progressValue.zero?
+ progressRect = dirtyRect
+ if @progressValue != KSKProgressIndicatorError
+ progressRect.size.width = ((@progressValue * NSWidth(dirtyRect)) / @maxProgressValue).floor
+ if @progressValue >= @maxProgressValue
+ gc = @@colorComponents[:greenGradiant]
+ else
+ gc = @@colorComponents[:blueGradiant]
+ end
+ else
+ gc = @@colorComponents[:redGradiant]
+ end
+ gradiantWithColors(gc).drawInRect(progressRect, angle: -90.0)
+ end
+
+ NSGraphicsContext.saveGraphicsState
+ NSColor.colorWithDeviceWhite(0.0, alpha: 0.2).set
+ NSBezierPath.setDefaultLineWidth(1.0)