Scriptable Timer / Stopwatch

Hello kel.

It is really interesting the thing with text in notifications, I hope I can come around to it, but maybe not for this, because I want to see for example, the task I am tracking, the start time, and the end time, the time elapsed, and the slack, that is an awful lot of data to cram into one notification. :confused:

But notifications are nice, for small messages, and having notifications initiated from an applet, with its own icon is even nicer, because then you can sort of collect all notifications in one place. (Now that I use a service, as well as the script, the notifications turns up in two different places.) You’ll also get a sort of “timeline”, when you see the notifications for one event in one place.

Notifications are also mouse centric, I believe. I can easily tab between the buttons on a dialog, and use space to select my choice, sometimes however, I like to operate mainly with the mose also, so there is an applet on the bedding now, so I can use the script from the Dock as well as from a short cut key, or the Script Menu. But the dialogs are still a favourite when using the mouse, since I then have bigger targets for the cursor, and I can still see all the data then, and all activity takes place in the middle of the screen…

I don’t even know how many buttons you can have on a notification, I guess you, can have three, I need three.

The last factor for cowarding out on notifications, is that I am soon to have the end result I want from this. Anyhow, you may reuse the code, if you can figure it out, and just ask if there is something. As I said, I am going to write a whole new post in code exchange, collecting all the bits and pieces.

:smiley: Hopefully without reintroducing any bugs, which is how it goes, when you edit the post, and forgets to update the source code.

Have a good evening.

Hi McUsr,

Looking forward to seeing your final app.

What I’m doing right now is thinking about how that notification dialog may be used in the timer. The algorithm needs be adjusted so as to use the buttons. Thinking about getting rid of the close button as I can’t get a response from it. Then, use quit as the close button maybe or switch the action button to the stop button. I still need to test out the buttons in the notification dialog. Everything needs to be moved around depending on what can be done with these new things.

Note that the third button or first is the content field where the static text is.

I was thinking that maybe if the static text is shorter, then maybe the actual third button might show in the notification. Need to test that out by using little or no static text. Needs experimenting. I’m having fun with the new toy!

Edited: and note that I’m still thinking about how to inform the user to click in the contents for something to happen (instead of a button). If you can think of a very good way to do that, it would be great.

Later,
kel

Just thought of something. Adding a picture as a target in the content. Maybe add a picture of a button or a bullseye might do it. I think that can be done!

Later,
kel

Almost there. Added separate subroutine for symetry:

script AppDelegate
	
	-- IBOutlets
	property theWindow : missing value

        property parent : class "NSObject"
        property myNotification : missing value
        property notificationCount: 0
        
        on applicationWillFinishLaunching_(aNotification)
            -- initialize
            return
        end applicationWillFinishLaunching_
        
        -- reopen handler
        on applicationShouldHandleReopen_hasVisibleWindows_(theApplication, aFlag)
            my applicationDidFinishLaunching_(missing value)
            return NO
        end applicationShouldHandleReopen_hasVisibleWindows_
        
        -- main
        on applicationDidFinishLaunching_(aNotification)
            -- set the delegate to script
            current application's NSUserNotificationCenter's defaultUserNotificationCenter's setDelegate_(me)
            -- get current date and target date
            set sentDate to current application's NSDate's |date|()
            set sentDateAsString to my formatDate_(sentDate,1,2)
            set numSeconds to 30
            set targetDate to current application's NSDate's dateWithTimeInterval_sinceDate_(numSeconds,sentDate)
            -- make user info NSDictionary
            set notificationCount to notificationCount + 1
            set nsDict to current application's NSDictionary's dictionaryWithObjectsAndKeys_(notificationCount, "notificationIndex", sentDateAsString, "sentDate", "value3", "key3", missing value)
            -- send notification to NSUserNotificationCenter
            my sendNotification_("MyNotifier",sentDateAsString,"It's time!","Restart","Stop",targetDate,"Boing",nsDict)
            say "Notification sent."
            return
        end applciationDidFinishLaunching_
        --
        
        -- format NSDate to string using styles
        -- 0 = none, 1 = short, 2 = med, 3 = long, 4 = full
        on formatDate_(aNSDate, aDateStyle, aTimeStyle)
            set myFormatter to current application's NSDateFormatter's alloc()'s init()
            myFormatter's setDateStyle_(aDateStyle)
            myFormatter's setTimeStyle_(aTimeStyle)
            set formattedDate to myFormatter's stringFromDate_(aNSDate)
            return formattedDate
        end formatDate_
        
        -- method for sending a notification
        on sendNotification_(aTitle, aSubtitle, aMessage, aActionButtonTitle, aOtherButtonTitle, aDeliveryDate, aSound, aDict)
            -- make the notification
            set myNotification to current application's NSUserNotification's alloc()'s init()
            set myNotification's title to aTitle
            set myNotification's subtitle to aSubtitle
            set myNotification's informativeText to aMessage
            set myNotification's actionButtonTitle to aActionButtonTitle
            set myNotification's otherButtonTitle to aOtherButtonTitle
            set myNotification's deliveryDate to aDeliveryDate
            set myNotification's soundName to aSound
            set myNotification's userInfo to aDict
            set myNotification's hasReplyButton to true
            -- schedule the notification
            current application's NSUserNotificationCenter's defaultUserNotificationCenter's scheduleNotification_(myNotification)
            return
        end sendNotification_
        
        -- delegate instance methods
        -- force presentation for when application process is frontmost
        on userNotificationCenter_shouldPresentNotification_(aCenter, aNotification)
            return yes
        end userNotificationCenter_shouldPresentNotification_
        
        -- deliver
        on userNotificationCenter_didDeliverNotification_(aCenter, aNotification)
            say "Notification Delivered"
            return
        end userNotificationCenter_didDeliverNotification_
        
        -- user activation
        on userNotificationCenter_didActivateNotification_(aCenter, aNotification)
            say "Notification Activated"
            -- 0    none
            -- 1    contents clicked
            -- 2    action button clicked
            -- 3    extra button clicked
                -- Gets user entry from notification's text field
            set userActivationType to (aNotification's activationType) as integer
            if userActivationType is 1 then
                say "contents clicked"
                -- note: eliminated option 0
                my contentsClicked_(aNotification)
                else if userActivationType is 2 then
                say "action button clicked"
                my actionButtonClicked_(aNotification)
                else if userActivationType is 3 then -- userActivationType is 3
                say "user activation type is 3"
                my replyButtonClicked_(aNotification)
                else if userActivationType is 4 then
                beep 3
            end if
            return userActivationType
        end userNotificationCenter_didActivateNotification_
        
        --
        on contentsClicked_(aNotification)
            -- do something
            return
        end contentsClicked_
        
        -- gets user reply in text field
        on replyButtonClicked_(aNotification)
            set userTextEntry to aNotification's response
            log userTextEntry
            return true
        end replyButtonClicked_
        
        -- gets user info and deletes delivered notification from Notification Center
        on actionButtonClicked_(aNotification)
            -- delete the notification and send a new one (or some other action)
            -- first get info on notification
            set theInfo to aNotification's userInfo
            set theValue to theInfo's valueForKey_("notificationIndex")
            say (theValue as string)
            -- delete notification from notification center
            current application's NSUserNotificationCenter's defaultUserNotificationCenter's removeDeliveredNotification_(aNotification)
            -- send a new notification
            my applicationDidFinishLaunching_(missing value)
            return
        end actionButtonClicked_
        
        --
        
        on applicationShouldTerminateAfterLastWindowClosed_()
            return true
        end applicationShouldTerminateAfterLastWindowClosed_
        
        -- quit
        on applicationShouldTerminate_(sender)
            -- Insert code here to do any housekeeping before your application quits 
            return current application's NSTerminateNow
        end applicationShouldTerminate_

	
end script

Getting there. Now how to get the actual text? It doesn’t seem to conform to the regular stuff. Need to go back and look at the class of the info maybe. Strange, unless I’m doing something wrongly.

gl,
kel

Darn, how did this line get in there:
my applicationDidFinishLaunching_(missing value)
Need to look back and see if that did anything in my thinking. Maybe not.

Oh no that’s supposed to be there I think. I was looking in the wrong place.

Think I know what is wrong. When the button is reply button clicked it’s not the same time as when the user presses return or the button after entering the text I think. Need to check that out.

It looks interesting kel.

I’m sure you’ll figure it out, Good luck.

P.S Have you checked out the AsobjC forum?

Next up here, is to set up Shane’s AsObjC Extras, I am going to use a lot more AsObjC from now on. :slight_smile:

Disregard the last statement. The reply is not received until the user enters the text. Think I know, now. Need to coerce the user entry to text.

Darn, almost there!

You should really skim the docs for NSNotificationCentre if you haven’t done so already. I guess you must pull an NSString out of the NSResponse object?? Best of luck kel. I am deadbeat after yester day. :slight_smile:

This line:
set userTextEntry to aNotification’s response
You can’t coerce to text. Darn Can’t remember how to do that or is it a new data form. But the document says that it is text I think.

Hi McUsr,

Yes, I’ve been reading the documentation for several days and I said it’s new so part of that was just navigating through it. Still can’t get the text for AppleScript. It will probably end up being something simple. Where’s Stefan when you need him :D.

Later,
kel

I think I remember now. You need to coerce it to text in the AppleScrpt OBjC environment. i.e. you can’t bring the data back to just AppleScript and try to coerce it. That must be it. Now how does this pertain to it. Don’t know if it will work somehow.

I’m thinking that I might use string instead of text. Could that be it?

Still can’t get this line to work:

It doesn’t work as string also. Can’t figure that out. Maybe need to look at the class of the object. Yeah, maybe it’s a record or something else.

The response property is an attributed string. You probably want something like:

set userTextEntry to (aNotification's response()'s |string|()) as text

The documents say that it is text:

Unless an nsAttributeString is different from nesting. that might be it?

I think a nsAttribute String might be a record. Looking through the docks:

An attributed string identifies attributes by name, using an NSDictionary object to store a value under the given name. You can assign any attribute name/value pair you wish to a range of characters”it is up to your application to interpret custom attributes (see Attributed String Programming Guide). If you are using attributed strings with the Core Text framework, you can also use the attribute keys defined by that framework. In iOS, standard attribute keys are described in the "Constants" section of NSAttributedString UIKit Additions Reference. In OS X, standard attribute keys are described in the "Constants" section of NSAttributedString AppKit Additions Reference.

S, the simple solution would be to just coerce to AppleScript record and see what you get.

No, that’s telling you it’s an NSAttributedString – that’s a different kettle of fish altogether. To get the text from it, you use the -string method, which needs pipes because of the terminology clash. Hence my previous post.

No, no, no…

set userTextEntry to (aNotification's response()'s |string|()) as text