[macruby-changes] [614] MacRuby/trunk/sample-macruby

source_changes at macosforge.org source_changes at macosforge.org
Mon Sep 22 19:11:48 PDT 2008


Revision: 614
          http://trac.macosforge.org/projects/ruby/changeset/614
Author:   psychs at limechat.net
Date:     2008-09-22 19:11:48 -0700 (Mon, 22 Sep 2008)
Log Message:
-----------
Added GrowlNotifier sample

Added Paths:
-----------
    MacRuby/trunk/sample-macruby/GrowlNotifier/
    MacRuby/trunk/sample-macruby/GrowlNotifier/growl.rb
    MacRuby/trunk/sample-macruby/GrowlNotifier/growl_block_sample.rb
    MacRuby/trunk/sample-macruby/GrowlNotifier/growl_delegate_sample.rb
    MacRuby/trunk/sample-macruby/GrowlNotifier/growl_helpers.rb

Added: MacRuby/trunk/sample-macruby/GrowlNotifier/growl.rb
===================================================================
--- MacRuby/trunk/sample-macruby/GrowlNotifier/growl.rb	                        (rev 0)
+++ MacRuby/trunk/sample-macruby/GrowlNotifier/growl.rb	2008-09-23 02:11:48 UTC (rev 614)
@@ -0,0 +1,156 @@
+framework 'Cocoa'
+
+module Growl
+  class Notifier < NSObject
+    VERSION = '1.0.1'
+    
+    GROWL_IS_READY = "Lend Me Some Sugar; I Am Your Neighbor!"
+    GROWL_NOTIFICATION_CLICKED = "GrowlClicked!"
+    GROWL_NOTIFICATION_TIMED_OUT = "GrowlTimedOut!"
+    GROWL_KEY_CLICKED_CONTEXT = "ClickedContext"
+    
+    PRIORITIES = {
+      :emergency =>  2,
+      :high      =>  1,
+      :normal    =>  0,
+      :moderate  => -1,
+      :very_low  => -2,
+    }
+    
+    class << self
+      # Returns the singleton instance of Growl::Notifier with which you register and send your Growl notifications.
+      def sharedInstance
+        @sharedInstance ||= alloc.init
+      end
+    end
+    
+    attr_reader :application_name, :application_icon, :notifications, :default_notifications
+    attr_accessor :delegate
+    
+    # Registers the applications metadata and the notifications, that your application might send, to Growl.
+    # The +default_notifications+ are notifications that will be enabled by default, the regular +notifications+ are
+    # optional and should be enabled by the user in the Growl system preferences.
+    #
+    # Register the applications name and the notifications that will be used.
+    # * +default_notifications+ defaults to the regular +notifications+.
+    # * +application_icon+ defaults to NSApplication.sharedApplication.applicationIconImage.
+    #
+    #   Growl::Notifier.sharedInstance.register 'FoodApp', ['YourHamburgerIsReady', 'OhSomeoneElseAteIt']
+    #
+    # Register the applications name, the notifications plus the default notifications that will be used and the icon that's to be used in the Growl notifications.
+    #
+    #   Growl::Notifier.sharedInstance.register 'FoodApp', ['YourHamburgerIsReady', 'OhSomeoneElseAteIt'], ['DefaultNotification], NSImage.imageNamed('GreasyHamburger')
+    def register(application_name, notifications, default_notifications = nil, application_icon = nil)
+      @application_name, @application_icon = application_name, (application_icon || NSApplication.sharedApplication.applicationIconImage)
+      @notifications, @default_notifications = notifications, (default_notifications || notifications)
+      @callbacks = {}
+      send_registration!
+    end
+    
+    # Sends a Growl notification.
+    #
+    # * +notification_name+ : the name of one of the notifcations that your apllication registered with Growl. See register for more info.
+    # * +title+ : the title that should be used in the Growl notification.
+    # * +description+ : the body of the Grow notification.
+    # * +options+ : specifies a few optional options:
+    #   * <tt>:sticky</tt> : indicates if the Grow notification should "stick" to the screen. Defaults to +false+.
+    #   * <tt>:priority</tt> : sets the priority level of the Growl notification. Defaults to 0.
+    #   * <tt>:icon</tt> : specifies the icon to be used in the Growl notification. Defaults to the registered +application_icon+, see register for more info.
+    #
+    # Simple example:
+    #
+    #   name = 'YourHamburgerIsReady'
+    #   title = 'Your hamburger is ready for consumption!'
+    #   description = 'Please pick it up at isle 4.'
+    #   
+    #   Growl::Notifier.sharedInstance.notify(name, title, description)
+    #
+    # Example with optional options:
+    #
+    #   Growl::Notifier.sharedInstance.notify(name, title, description, :sticky => true, :priority => 1, :icon => NSImage.imageNamed('SuperBigHamburger'))
+    #
+    # When you pass notify a block, that block will be used as the callback handler if the Growl notification was clicked. Eg:
+    #
+    #   Growl::Notifier.sharedInstance.notify(name, title, description, :sticky => true) do
+    #     user_clicked_notification_so_do_something!
+    #   end
+    def notify(notification_name, title, description, options = {}, &callback)
+      dict = {
+        :ApplicationName => @application_name,
+        :ApplicationPID => pid,
+        :NotificationName => notification_name,
+        :NotificationTitle => title,
+        :NotificationDescription => description,
+        :NotificationPriority => PRIORITIES[options[:priority]] || options[:priority] || 0
+      }
+      dict[:NotificationIcon] = options[:icon].TIFFRepresentation if options[:icon]
+      dict[:NotificationSticky] = 1 if options[:sticky]
+      
+      context = {}
+      context[:user_click_context] = options[:click_context] if options[:click_context]
+      if block_given?
+        @callbacks[callback.object_id] = callback
+        context[:callback_object_id] = callback.object_id.to_s
+      end
+      dict[:NotificationClickContext] = context unless context.empty?
+      
+      notification_center.postNotificationName :GrowlNotification, object:nil, userInfo:dict, deliverImmediately:true
+    end
+    
+    def onReady(notification)
+      send_registration!
+    end
+    
+    def onClicked(notification)
+      user_context = nil
+      if context = notification.userInfo[GROWL_KEY_CLICKED_CONTEXT]
+        user_context = context[:user_click_context]
+        if callback_object_id = context[:callback_object_id]
+          @callbacks.delete(callback_object_id.to_i).call
+        end
+      end
+      
+      @delegate.growlNotifierClicked_context(self, user_context) if @delegate && @delegate.respond_to?(:growlNotifierClicked_context)
+    end
+    
+    def onTimeout(notification)
+      user_context = nil
+      if context = notification.userInfo[GROWL_KEY_CLICKED_CONTEXT]
+        @callbacks.delete(context[:callback_object_id].to_i) if context[:callback_object_id]
+        user_context = context[:user_click_context]
+      end
+      
+      @delegate.growlNotifierTimedOut_context(self, user_context) if @delegate && @delegate.respond_to?(:growlNotifierTimedOut_context)
+    end
+    
+    private
+    
+    def pid
+      NSProcessInfo.processInfo.processIdentifier.to_i
+    end
+    
+    def notification_center
+      NSDistributedNotificationCenter.defaultCenter
+    end
+    
+    def send_registration!
+      add_observer 'onReady:', GROWL_IS_READY, false
+      add_observer 'onClicked:', GROWL_NOTIFICATION_CLICKED, true
+      add_observer 'onTimeout:', GROWL_NOTIFICATION_TIMED_OUT, true
+      
+      dict = {
+        :ApplicationName => @application_name,
+        :ApplicationIcon => application_icon.TIFFRepresentation,
+        :AllNotifications => @notifications,
+        :DefaultNotifications => @default_notifications
+      }
+      
+      notification_center.postNotificationName :GrowlApplicationRegistrationNotification, object:nil, userInfo:dict, deliverImmediately:true
+    end
+    
+    def add_observer(selector, name, prepend_name_and_pid)
+      name = "#{@application_name}-#{pid}-#{name}" if prepend_name_and_pid
+      notification_center.addObserver self, selector:selector, name:name, object:nil
+    end
+  end
+end

Added: MacRuby/trunk/sample-macruby/GrowlNotifier/growl_block_sample.rb
===================================================================
--- MacRuby/trunk/sample-macruby/GrowlNotifier/growl_block_sample.rb	                        (rev 0)
+++ MacRuby/trunk/sample-macruby/GrowlNotifier/growl_block_sample.rb	2008-09-23 02:11:48 UTC (rev 614)
@@ -0,0 +1,29 @@
+require 'rubygems'
+require 'growl_helpers'
+
+class GrowlController < NSObject
+  # Makes the #growl and #sticky_growl shortcut methods available.
+  include Growl
+  
+  HELLO_TYPE = 'Hello message received'
+  Growl::Notifier.sharedInstance.register('GrowlSample', [HELLO_TYPE])
+  
+  def init
+    if super
+      growl HELLO_TYPE, 'Not sticky', 'Hello world' do
+        puts "Clicked not sticky: #{ Time.now }"
+        NSApp.terminate(nil)
+      end
+      
+      sticky_growl HELLO_TYPE, 'Sticky', 'Hello world' do
+        puts "Clicked sticky: #{ Time.now }"
+        NSApp.terminate(nil)
+      end
+      
+      self
+    end
+  end
+end
+
+g = GrowlController.alloc.init
+NSApp.run

Added: MacRuby/trunk/sample-macruby/GrowlNotifier/growl_delegate_sample.rb
===================================================================
--- MacRuby/trunk/sample-macruby/GrowlNotifier/growl_delegate_sample.rb	                        (rev 0)
+++ MacRuby/trunk/sample-macruby/GrowlNotifier/growl_delegate_sample.rb	2008-09-23 02:11:48 UTC (rev 614)
@@ -0,0 +1,36 @@
+require 'rubygems'
+require 'growl'
+
+class GrowlController < NSObject
+  HELLO_TYPE = 'Hello message received'
+  
+  def init
+    if super
+      @g = Growl::Notifier.sharedInstance
+      @g.delegate = self
+      @g.register('GrowlSample', [HELLO_TYPE])
+      @g.notify(HELLO_TYPE, 'Sticky', 'Hello world', :sticky => true, :click_context => Time.now.to_s )
+      @g.notify(HELLO_TYPE, 'Timed out', 'Hello world', :click_context => Time.now.to_s )
+      @count = 2
+      self
+    end
+  end
+
+  def growlNotifierClicked_context(sender, context)
+    puts "Clicked: #{context}"
+    checkCount
+  end
+
+  def growlNotifierTimedOut_context(sender, context)
+    puts "Timed out: #{context}"
+    checkCount
+  end
+  
+  def checkCount
+    @count -= 1
+    NSApp.terminate(nil) if @count == 0
+  end
+end
+
+g = GrowlController.alloc.init
+NSApp.run

Added: MacRuby/trunk/sample-macruby/GrowlNotifier/growl_helpers.rb
===================================================================
--- MacRuby/trunk/sample-macruby/GrowlNotifier/growl_helpers.rb	                        (rev 0)
+++ MacRuby/trunk/sample-macruby/GrowlNotifier/growl_helpers.rb	2008-09-23 02:11:48 UTC (rev 614)
@@ -0,0 +1,25 @@
+require File.expand_path('../growl', __FILE__)
+
+# Defines a few convenience methods that you can use in your class if you include the Growl module.
+# Eg:
+#
+#   class FoodReporter < NSObject
+#     include Growl
+#
+#     def hamburger_time!
+#       growl 'YourHamburgerIsReady', 'Your hamburger is ready for consumption!', 'Please pick it up at isle 4.', :priority => 1 do
+#         throw_it_away_before_user_reaches_counter!
+#       end
+#     end
+#   end
+module Growl
+  # Sends a Growl notification. See Growl::Notifier#notify for more info.
+  def growl(name, title, description, options = {}, &callback)
+    Growl::Notifier.sharedInstance.notify name, title, description, options, &callback
+  end
+  
+  # Sends a sticky Growl notification. See Growl::Notifier#notify for more info.
+  def sticky_growl(name, title, description, options = {}, &callback)
+    growl name, title, description, options.merge!(:sticky => true), &callback
+  end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080922/ceaecad3/attachment.html 


More information about the macruby-changes mailing list