Tuesday, September 2, 2014

#1 2011-06-18 09:48:25 am

Jonathan Engelhardt
Member
Registered: 2010-06-11
Posts: 24

Calling given Cocoa Method from applescript

Hey guys,

im struggling with a little problem over here. I got a cocoa method to draw a badge on an icon with numbers to get a visual feedback of a progress. i cant use the simple method provided for 10.6 and higher because this needs to run on a 10.4 machine.

Im good at applescript but not good with cocoa and the calling of methods. Heres the .m and .h file.
How do a call this method from applescript correctly? Any help aprreciated!


IconImageCounterController.h

Applescript:


#import <Cocoa/Cocoa.h>

@interface IconImageCounterController : NSObject {

NSImage *iconImageBuffer;
NSImage *originalIcon;
NSTimer *timer;
NSDictionary *attributes;
int count;
}
- (void)drawCountdownIcon:(int)number;
- (void)timerAction:(NSTimer *)_timer;

@end

IconImageCounterController.m

Applescript:


#import "IconImageCounterController.h"


@implementation IconImageCounterController

- (void)awakeFromNib {
if (timer) return;
originalIcon = [[NSApp applicationIconImage] copy];
iconImageBuffer = [originalIcon copy];
timer = [[NSTimer scheduledTimerWithTimeInterval:1
                                            target:self
                                           selector:@selector(timerAction:)
                                           userInfo:nil
                                            repeats:YES] retain];
attributes = [[NSDictionary alloc] initWithObjectsAndKeys:
                [NSFont fontWithName:@"Helvetica-Bold" size:26], NSFontAttributeName,
                [NSColor whiteColor], NSForegroundColorAttributeName, nil];
   
count = 20;
}

- (void)dealloc {
[originalIcon release];
[iconImageBuffer release];
[attributes release];
[super dealloc];
}

- (void)timerAction:(NSTimer *)_timer {
if (count < 0 && timer == _timer) {[timer invalidate]; [timer release]; timer = nil; return;}
[self drawCountdownIcon:count--];

}

- (void)drawCountdownIcon:(int)number {

NSString *countdown = [NSString stringWithFormat:@"%i", number];
NSSize numSize = [countdown sizeWithAttributes:attributes];
NSSize iconSize = [originalIcon size];
if (number) {
[iconImageBuffer lockFocus];
[originalIcon drawAtPoint:NSMakePoint(0, 0)
                        fromRect:NSMakeRect(0, 0, iconSize.width, iconSize.height)
                       operation:NSCompositeSourceOver
                        fraction:1.0f];
float max = (numSize.width > numSize.height) ? numSize.width : numSize.height;
max += 16;
NSRect circleRect = NSMakeRect(iconSize.width - max, iconSize.height - max, max, max);
NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:circleRect];
[[NSColor colorWithCalibratedRed:0.8f green:0.0f blue:0.0f alpha:1.0f] set];
[bp fill];
[countdown drawAtPoint:NSMakePoint(NSMidX(circleRect) - numSize.width / 2.0f,
                                        NSMidY(circleRect) - numSize.height / 2.0f + 2.0f)
               withAttributes:attributes];

[iconImageBuffer unlockFocus];
[NSApp setApplicationIconImage:iconImageBuffer];
}
else [NSApp setApplicationIconImage:originalIcon];

}

@end

i tried this here on an awake from nib (testwise), but nothing happens:

Applescript:


call method "drawCountdownIcon" of class "IconImageCounterController" with parameters {10}

Offline

 

#2 2011-06-18 12:18:07 pm

StefanK
Member
From: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 10490
Website

Re: Calling given Cocoa Method from applescript

Hi,

you can call methods of custom classes directly from AppleScript Studio only if they are class methods (starting with plus sign).

The other way is to create an instance of the class with the usual alloc/init methods

Applescript:


set iconImageCounterControllerInstance to (call method "init" of (call method "alloc" of class "IconImageCounterController"))
call method "drawCountdownIcon" of iconImageCounterControllerInstance with parameter 10

don't forget to release the instance object after having finished with it

Applescript:


call method "release" of iconImageCounterControllerInstance


regards

Stefan

Offline

 

#3 2011-06-18 01:14:04 pm

Jonathan Engelhardt
Member
Registered: 2010-06-11
Posts: 24

Re: Calling given Cocoa Method from applescript

Hi StefanK

Thank you for your answer. I tried what you told me but still nothing happens.
I think there might be a problem with the call i do.

As far as i understand the methods, i have to call the "drawCountdownIcon" method to draw a badge with the parameter (10) , but thaht might be completely wrong. Im still working on my cocoa skills (actually started with basics),but want to finish this applescript app. So could you please have a look at the method to figure out how to call it correctly? I'd aprreciate that.


EDIT: Additional question: As more as i get into the cocoa, the more i understand it. With the code you gave me, you created an instance of the object "iconImageCounterController". But how do you pass the variables (iconImageBuffer,originalIcon,timer,attributes,count?) from applescript?



Greetings
Jonathan

Last edited by Jonathan Engelhardt (2011-06-18 01:28:52 pm)

Offline

 

#4 2011-06-18 01:29:18 pm

StefanK
Member
From: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 10490
Website

Re: Calling given Cocoa Method from applescript

is the awakeFromNib handler be called at all in the Cocoa class?
It's important, because in this handler the main variables are set.

I haven't used AppleScript Studio for a long time,
as far as I remember you have to add a custom object (blue cube) in Interface Builder,
change the class name to your custom class and connect the delegate to files's owner

The parameter call should work as written.


regards

Stefan

Offline

 

#5 2011-06-18 03:13:09 pm

Jonathan Engelhardt
Member
Registered: 2010-06-11
Posts: 24

Re: Calling given Cocoa Method from applescript

Ah!
It works with Awake from nib connected in IB. First Sunlight at the end of the darkness!
But...

I rewrote the cocoa a little - it works if i use awake from nib to declare the vars, but i want to launch it from applescript. so i removed the awake from nib and build a new method "setbadge" where i declare the vars except of the number i want to display.
Everything works and is tested. Onliest thing that doesnt work is to call the method setBadge from Applescript like you mentionend in your second post.

IconImageCounterController.h file

Applescript:



#import <Cocoa/Cocoa.h>


@interface IconImageCounterController : NSObject {

NSImage *iconImageBuffer;
NSImage *originalIcon;
NSTimer *timer;
NSDictionary *attributes;
//int count;
}
- (void)setBadge:(int)count;
- (void)drawIcon:(int)number;


@end

IconImageCounterController.m file

Applescript:


#import "IconImageCounterController.h"


@implementation IconImageCounterController

- (void)setBadge:(int)count {
originalIcon = [[NSApp applicationIconImage] copy];
iconImageBuffer = [originalIcon copy];
   
attributes = [[NSDictionary alloc] initWithObjectsAndKeys:
                [NSFont fontWithName:@"Helvetica-Bold" size:26], NSFontAttributeName,
                [NSColor whiteColor], NSForegroundColorAttributeName, nil];    

   [self drawIcon:count];
}

- (void)dealloc {
[originalIcon release];
[iconImageBuffer release];
[attributes release];
[super dealloc];
}


- (void)drawIcon:(int)number {

NSString *countdown = [NSString stringWithFormat:@"%i", number];
NSSize numSize = [countdown sizeWithAttributes:attributes];
NSSize iconSize = [originalIcon size];
if (number) {
[iconImageBuffer lockFocus];
[originalIcon drawAtPoint:NSMakePoint(0, 0)
                        fromRect:NSMakeRect(0, 0, iconSize.width, iconSize.height)
                       operation:NSCompositeSourceOver
                        fraction:1.0f];
float max = (numSize.width > numSize.height) ? numSize.width : numSize.height;
max += 16;
NSRect circleRect = NSMakeRect(iconSize.width - max, iconSize.height - max, max, max);
NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:circleRect];
[[NSColor colorWithCalibratedRed:0.8f green:0.0f blue:0.0f alpha:1.0f] set];
[bp fill];
[countdown drawAtPoint:NSMakePoint(NSMidX(circleRect) - numSize.width / 2.0f,
                                        NSMidY(circleRect) - numSize.height / 2.0f + 2.0f)
               withAttributes:attributes];

[iconImageBuffer unlockFocus];
[NSApp setApplicationIconImage:iconImageBuffer];
}
else [NSApp setApplicationIconImage:originalIcon];

}

@end

leaned onto your script,  i try this, doesnt work

Applescript:


on awake from nib theObject
   log "awake..." --handler works!
   try
       set iconImageCounterControllerInstance to (call method "init" of (call method "alloc" of class "IconImageCounterController"))        
       call method "setBadge" of iconImageCounterControllerInstance with parameter 10
       call method "release" of iconImageCounterControllerInstance
   on error err
       log err
   end try
   
end awake from nib

Offline

 

#6 2011-06-18 03:32:11 pm

StefanK
Member
From: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 10490
Website

Re: Calling given Cocoa Method from applescript

sorry, I forgot, if the method has parameter(s), you have to add the appropriate colons

Applescript:


call method "setBadge:" of iconImageCounterControllerInstance with parameter 10

Last edited by StefanK (2011-06-18 03:36:09 pm)


regards

Stefan

Offline

 

#7 2011-06-19 04:45:39 am

Jonathan Engelhardt
Member
Registered: 2010-06-11
Posts: 24

Re: Calling given Cocoa Method from applescript

Thats it!!!

Thank you very much! smile

last question:

when im done with what i need to do, do i need to to call the method "dealloc"?

Applescript:


- (void)dealloc {
[originalIcon release];
[iconImageBuffer release];
[attributes release];
[super dealloc];
}

Last edited by Jonathan Engelhardt (2011-06-19 04:54:29 am)

Offline

 

#8 2011-06-19 10:05:22 am

StefanK
Member
From: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 10490
Website

Re: Calling given Cocoa Method from applescript

Jonathan Engelhardt wrote:

T
when im done with what i need to do, do i need to to call the method "dealloc"?

No, never call dealloc in custom methods.
The method will be called from the parent class automatically after releasing the object


regards

Stefan

Offline

 

#9 2011-07-01 02:19:56 pm

Jonathan Engelhardt
Member
Registered: 2010-06-11
Posts: 24

Re: Calling given Cocoa Method from applescript

Everything works! Thank you very much!

Offline

 

Board footer

Powered by FluxBB

[ Generated in 0.049 seconds, 10 queries executed ]

RSS (new topics) RSS (active topics)