Skip to content

Instantly share code, notes, and snippets.

@danielwestendorf
Created December 8, 2011 22:25
Show Gist options
  • Save danielwestendorf/1448953 to your computer and use it in GitHub Desktop.
Save danielwestendorf/1448953 to your computer and use it in GitHub Desktop.
Desktop Notifications for MacRuby
#
# MRNotification.rb
#
# Created by Daniel Westendorf on 12/8/11.
# MIT Licensed, use as you wish as-is.
framework 'Cocoa'
class MRNotifier
def initialize(d_options={})
options = {:width => 275, :height => 100, :spacing => 20}
options.merge!(d_options)
@panels = []
@width = options[:width]; @height = options[:height]; @spacing = options[:spacing]
end
def add_notification(passed_options={})
default_options = {:title => '', :ttl => 10, :message => ''}
options = default_options.merge(passed_options)
rect = self.get_rect
panel = NSPanel.alloc.initWithContentRect(rect,
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSUtilityWindowMask |NSHUDWindowMask,
backing:NSBackingStoreBuffered,
defer:false)
#set the content
if options[:image]
options[:image].setSize(NSSize.new(50,50))
total_frame = panel.contentView.frame
text_frame = [total_frame.origin.x + 55, total_frame.origin.y, total_frame.size.width - 55, total_frame.size.height - 5]
img_view = NSImageView.alloc.init.setImage(options[:image])
panel.contentView.addSubview(img_view)
panel.contentView.subviews[0].setFrame([total_frame.origin.x + 5, total_frame.size.height - 60, 50, 50])
else
total_frame = panel.contentView.frame
text_frame = NSRect.new([total_frame.origin.x + 5, total_frame.origin.y - 5], [total_frame.size.width - 10, total_frame.size.height - 10])
end
panel.setTitle(options[:title])
text = NSTextView.alloc.initWithFrame(text_frame)
text.setDrawsBackground(false)
text.setFont(NSFont.userFontOfSize(13))
text.setTextColor(NSColor.lightGrayColor)
text.setString(options[:message])
panel.contentView.addSubview(text)
#panel settings
panel.setHidesOnDeactivate(false)
panel.setReleasedWhenClosed(true)
panel.orderFrontRegardless
panel.setMovable(false)
@panels << panel
NSTimer.scheduledTimerWithTimeInterval(options[:ttl], target: self, selector:"remove_panel:", userInfo:panel, repeats:false)
NSNotificationCenter.defaultCenter.addObserver(self, selector:'notification_closed:', name:NSWindowWillCloseNotification, object: panel)
panel.display
end
def notification_closed(notification)
@panels.delete(notification.object)
end
def get_rect
screen = NSScreen.screens[0].visibleFrame
base_x = screen.size.width - @width - @spacing
base_y = screen.size.height - @height
x = base_x
y = base_y
unless @panels.length < 1
origins = @panels.collect {|panel| [panel.frame.origin.x, panel.frame.origin.y]}
while origins.include?([x,y])
if ((y - @height - @spacing * 2) > screen.origin.y)
y -= (@height + @spacing * 2)
else
y = base_y
x -= (@width + @spacing)
end
end
end
return [x, y, @width, @height]
end
def remove_panel(timer)
@panels.delete(timer.userInfo)
timer.userInfo.close
end
end
#usage
#Create the notifier queue. Accepts hash of options
# :width == Width of notifications default: 275
# :height == Height of notifications default: 100 (Images have a fixed height of 50, go lower, you will not)
# :spacing == Spacing between new notifications default: 20
notification_queue = MRNotifier.new({:height => 120, :width => 50, :spacing 50})
#Publish a notification. Accepts hash of options
# :title == string title of window default: blank
# :ttl == time the notification should stay on screen in seconds default: 10
# :message == meat of the notification, human word glob representation of your notification default: blank
# :image == NSImage that you want displayed in your notification default: none
notification_queue.add_notification({:title => "DANGER WILL ROBINSON!", :message => "If it burns when you pee, you may have the clap", :ttl => 5, :image => NSImage.imageNamed('my_app_icon.png'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment