I’m a newbie in applescript studio but i’ve writed in the past hypercard stacks. I want to get a word clicked (in a text view) to play a sound. For example if i click on the word “mouse”, the sound “mouse” is played. It was possible with hypercard but i can’t found with applescript studio
unfortunately handling mouse clicks on single words/characters in a text view is not a standard feature. I don’t think it’s possible with AppleScript.
Here’s a solution using some Objective-C - implemented as a subclass of NSTextView. Since you wrote you were a ‘newbie’ here a step by step guide:
in Interface Builder:
click the ‘Classes’ tab of the Nib’s document window
select your Text View (not it’s enclosing scroll view)
in the Classes tab you should now see the object hierarchy to NSTextView selected
Ctrl-Click or Right-Mousebutton-Click (Context Menu) on the class NSTextView and choose ‘Subclass NSTextView’
Name the new Subclass - for example MyTextView
Choose ‘Create files for …’ from the new subclasses context menu
select your text view again and choose ‘Custom Class’ from the Inspector window (or activate it by pressing Apple + 5)
choose the new subclass for your text view
in the Instances Tab of the nib’s document window: connect File’s Owner to at least one of the handlers in your script
in Xcode:
add a handler like this in your script:
on clickedWord(theWord)
say theWord -- for example
end clickedWord
edit the subclass file MyTextView.m:
#import "MyTextView.h"
@implementation MyTextView
- (void)awakeFromNib {
[[self window] setAcceptsMouseMovedEvents:YES];
}
- (void)mouseDown:(NSEvent *)theEvent{
NSLayoutManager *layoutManager = [self layoutManager];
NSTextContainer *textContainer = [self textContainer];
unsigned glyphIndex, charIndex;
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
NSRange lineGlyphRange, lineCharRange, wordCharRange;
NSRect glyphRect;
// Convert view coordinates to container coordinates
point.x -= [self textContainerOrigin].x;
point.y -= [self textContainerOrigin].y;
// Convert those coordinates to the nearest glyph index
glyphIndex = [layoutManager glyphIndexForPoint:point inTextContainer:textContainer];
// Check to see whether the mouse actually lies over the glyph it is nearest to
glyphRect = [layoutManager boundingRectForGlyphRange:NSMakeRange(glyphIndex, 1) inTextContainer:textContainer];
if (NSPointInRect(point, glyphRect)) {
// Convert the glyph index to a character index
charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
// Determine the range of glyphs, and of characters, in the corresponding line
(void)[layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:&lineGlyphRange];
lineCharRange = [layoutManager characterRangeForGlyphRange:lineGlyphRange actualGlyphRange:NULL];
// Determine the word containing that character
wordCharRange = NSIntersectionRange(lineCharRange, [self selectionRangeForProposedRange:NSMakeRange(charIndex, 0) granularity:NSSelectByWord]);
NSString *clickedWord = [[self string] substringWithRange:wordCharRange];
NSAppleScript *callASHandler = [[NSAppleScript alloc] initWithSource:
[NSString stringWithFormat:@"(get my script)'s clickedWord(\"%@\")",clickedWord]];
[callASHandler executeAndReturnError:nil];
[callASHandler release];
}
[super mouseDown];
}
@end
unsigned int glyphIndex = [lm glyphIndexForPoint:mousePoint inTextContainer:tc fractionOfDistanceThroughGlyph:NULL];
NSRect glyphBounds = [lm boundingRectForGlyphRange:NSMakeRange(glyphIndex, 1) inTextContainer:tc];
if (NSPointInRect(mousePoint, glyphBounds)) {
NSTextStorage *ts = [self textStorage];
unsigned int charIndex = [lm characterIndexForGlyphAtIndex:glyphIndex];
/*** Apple's documentation of -doubleClickAtIndex: ***
Returns the range of characters that form a word (or other linguistic unit) surrounding the given index, taking language characteristics into account.
*/
NSRange stringRange = [ts doubleClickAtIndex:charIndex];
NSString *clickedString = [[ts string] substringWithRange:stringRange];
// Reject if string is only whitespace
NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
clickedString = [clickedString stringByTrimmingCharactersInSet:charSet];
if (![clickedString isEqualToString:@""]) {
// Do something with string
NSLog(clickedString);
}
}
}[/code]
Additions have also been included to reject whitespace-only strings.
The problem is getting the required word under the mouse, not receiving mouse events.
Hello !
It’s Yvo again.
I’m trying to apply the contents of these messages.
I can’t understand how connect Files’s Owner (an icon with the A of application in the instances tab) with the handler.
What Handler ? the applescript file?
Thanxs 4 your replies
quote
in the Instances Tab of the nib’s document window: connect File’s Owner to at least one of the handlers in your script
/quote
Thanxxxxxxs you Dominik !
It’s run !
Like it, i can continue to write a small program for the schoolchilds of my class : a program that show images with the word and play the sound of the word (also with the syllabes, phonèmes and the name of the letters).
I’m a teacher !
If i can write this program with the images drawn by schoolchild (for the moment i can use image copyrighted from a schoolbook) and maybe their voices, i will publish it freely and i will post here the link for the download. I will acknowledge strongly Dominik and the MacScripter (bbs.applescript.net).