Scriptable Timer / Stopwatch

Opening and closing and opening a new window is not very elegant. Darn, might need to go out of ASObjC for vanilla mac.

One other option might be to use the Switch Control. Need to look into that again.

Edited: don’t mind me. Just talking to myself. :slight_smile:

Hello kel.

I think I won’t try to combine a stopwatch and a count down timer with an AppleScript.

But I could add a script, that reads out the properties so far, so that you could “inspect” the stopwatch so to speak for a “intermediary-time”. :slight_smile: That was a great idea. One of the ideas behind making it as a script, is to be able to journal, or “clock” something without adding yet another process to do it, so that I don’t have to have a “stopwatch-server” running at all times, I am prepared to add whatever I need into the stopwatch process. :slight_smile:

I haven’t written this probably, but my idea also was to avoid having lots of messages saying how long time things have taken so far, and so on, to make it as “quiet” as possible. Stress-free journaling, so that I focus on getting things done in a best possible way, without having to consider the time spent on achieving the best result. :smiley: That however, doesn’t contradict the need to see how long time has passed since I started doing this and that. That should be possible. Again, thanks kel, great idea!

Hi McUsr,

Just started reading (more in depth) the new documentation for userNotificationCenter and found that they have added a lot more. Maybe there is a third button and reply to the delegate from the close button. Still reading and checking it out.

Edited: think they’ve added a way to see when the user clicks the close button by using the NSUserNotificationActivationTypeReplied. This is very good and completes it if it works. This is very good! Before, you could only find out if the user clicked the close button by monitoring the notification window! :smiley:

Edited: and by the way, monitoring the window caused the app to use too much cpu.

Have a good day,
kel

Hi McUsr,

I’ll have to rewrite the template notification script. It’s very different now and needs testing again.

Later,
kel

Hello kel.

That sounds very interesting, I’ll drop by tomorrow too, with the next version of the StopWatch-skeleton. :slight_smile:

It’s still incomplete. :frowning: Unless the new updates are in there, but just not in the documentation.

Maybe your way is better. Just keep it simple. Then you don’t need to wait for the updates. Still can dream! :smiley:

Have a great day McUsr,
kel

Hi McUsr,

The has reply button works! :smiley: Needs experimenting. You can enter text! Nice stuff. Check it out man.

It seems like using the has reply button gives more options than just the action button. Seems like It’s a replacement for the action button. Great!!! New toy.

Later,
kel

Also, It’s a bigger notification window. Something like a floating dialog window. Nice stuff. I’ll try to translate it to an AppleScript Objective C later.

Later,
kel

If you want to try it out, all I did was add the line:

to the sendNotification_ subroutine. Just added it to the slightly modified template:

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
            set userActivationType to (aNotification's activationType) as integer
            if userActivationType is 1 then
                say "contents clicked"
                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 "no user activation"
            end if
            return userActivationType
        end userNotificationCenter_didActivateNotification_
        
        --
        on contentsClicked_(aNotification)
            -- do something
            return
        end contentsClicked_
        
        -- 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

Thinking how to get the user entry text and cutting out all the extraneous stuff for now.

Edited: one more thing. Changed the o0 activation type from 0 to 3 and added this line in the Xcode:

So, when the user hits the Reply button, that’s why it says “no user activation”. I was just testing and trying to get feedback.

Later,
kel

One more thing I think they might have added is the identifier property for the notification, but maybe not. Still checking into that. What this might allow you to do is update the notification window and hopefully in real time.

Need another subroutine to get the user entry after the user hits the Reply button and can’t find it in the documentation. What good is text entry if you can’t get the text? It’s a puzzle.

Hello kel.

For my use, (I really have no need for entering text thru a notification), it would just be great if you manage to get the state of a button back, or call a handler if it is clicked.

I thought it would be great to launch a journal, if a user clicks the button of the notification. Like: “Timing stopped” as a notification with a “launch journal” button.

I also hope it doesn’t have to be in a “stay open” applet, but it is no big deal if it doesn’t work out of course, because I can really have three buttons on the stop dialog when the script ends. :slight_smile:

Enjoy your evening.

Hi McUsr,

The thing is if you translate the Xcode app to AppleScript, then it doesn’t need to be stay opened.

Just for my own thoughts, I’m trying to get back the user entry in the text field. Maybe, there might be a breakthrough:
NSUserNotificationActivationTypeAdditionalActionClicked = 4
I haven’t tried to see if anything is returned when the user enters text and the app checks for activation type 4 yet. Need to go to the store at the moment, but will be looking into this.

Your script is great, but I was still thinking that for myself it might be good if I could sidestep the display dialogs. Note that you can’t get the name of some processes. It might be rare, but it happens.

Later,
kel

I’m currently testing it kel, after having made it more modular, and you just use it as you like for your own purposes, when it is finished, all dialogs are factored out. :slight_smile:

Just got back. Looking for your no display dialog dialog app!

Still wish I could get the text entry from the Notification window. Might need to use uielement scripting somehow. :expressionless:

Aloha,
kel

Hi McUsr,

Just some constructive criticism.

The user should be able to stop the watch without opening a dialog. That way, user can stop the timer at anytime instead of going through the dialog and pressing the button. That’s another part of the dialog problem. Another method might be to use keystrokes as I wrote in the earlier posts. Then, you can stop the stopwatch on the fly almost.

Later,
kel

Hello.

The StopWatch has been moved to Code Exchange.

Hello kel.

I don’t share your view, but thanks for the feedback, when the dialog is open, then I can use the tab key, to move around and select the choice I want.
There is another reason too. This makes the user, understand what is going on, or what has happened, because sitting and timing stuff while you work, can soon be confusing, if you use keystrokes, at least if you don’t get any feedback. (my experience). I really like the dialogs, because that gives a controlled experience.

I hope you try the next version in the post above , you may use it to make your own version, without dialogs. :slight_smile:

Hi McUsr,

You have been busy! You cracked me up with the reintroducing of the bug! :smiley:

If you interested, by trial and error I found out how to get the user’s in the notification’s text field’s response with ‘response’ :). Here’s the test subroutine from the old template:

        on userNotificationCenter_didActivateNotification_(aCenter, aNotification)
            say "Notification Activated"
            -- 0    none
            -- 1    contents clicked
            -- 2    action button clicked
            set userActivationType to (aNotification's activationType) as integer
            if userActivationType is 1 then
                say "contents clicked"
                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
                set x to aNotification's response
                log x
                say "user activation type 3"
            end if
            return userActivationType
        end userNotificationCenter_didActivateNotification_

→ 2015-04-13 08:19:44.751 NotificationTimer[1776:88657] hello{
}
Slowly getting there.

Edited: and btw I made a fool of myself so many times that I’ve become immune to it :). At least we try and it sometimes it doesn’t work out, but that’s the way it goes. :wink:

Edited: and another btw, when you succeed it brings great satisfaction and helps many people some of which are more lost than we are.

Later,
kel