#!/usr/bin/env ruby # # 2006-06-11 modified by FUJIMOTO Hisa for the lightning talk session # at RubyKaigi2006 http://jp.rubyist.net/RubyKaigi2006/. # usage: ruby countdown.rb MINUTE # # original written by Chris Thomas for the article of DDJ May 2002. # require 'osx/cocoa' require 'time' require 'fileutils' LT_START_TIME_PATH = "/tmp/rubykaigi_lt_start_time.txt" class HelloView < OSX::NSView attr_accessor :total_sec attr_reader :start_time def initialize @total_sec = 60 * 5 @start_time = if File.exist?(LT_START_TIME_PATH) then Time.parse(File.read(LT_START_TIME_PATH)) else t = Time.now File.open(LT_START_TIME_PATH,"w") {|f| f.write(t) } t end end # # When the Cocoa view system wants to draw a view, # it calls the method -(void)drawRect:(NSRect)rect. # The rectangle argument is relative to the origin # of the view's frame, and it may only be a small # portion of the view. For this reason, very # simple views with only one or two graphical # elements tend to ignore this parameter. # def drawRect(rect) # Set the window background to transparent OSX::NSColor.clearColor.set OSX::NSRectFill(bounds) # Draw the text in a shade of red and in a large system font attributes = OSX::NSMutableDictionary.alloc.init attributes.setObject_forKey(current_color, OSX.NSForegroundColorAttributeName ) attributes.setObject_forKey( OSX::NSFont.boldSystemFontOfSize(48.0), OSX.NSFontAttributeName ) # string = OSX::NSString.alloc.initWithString( "Hello, Ruby Baby" ) string = OSX::NSString.alloc.initWithString(sec_to_s) string.drawAtPoint_withAttributes([0,0], attributes) # # Turn the window's shadow off and on -- # This is a kludge to get the shadow to recalculate # for the new shape of the opaque window content. # viewWindow = window window.setHasShadow(0) window.setHasShadow(1) end def sec_to_s t = sec min = (t.abs / 60).to_i sec = (t.abs % 60).to_i format("%s%02d:%02d", (t<0)?"-":" ", min, sec) end def sec total_sec - (Time.now - start_time).to_i end def current_color x = sec @color = if sec < 0 then OSX::NSColor.purpleColor elsif sec < 60 then OSX::NSColor.redColor elsif sec < 120 then OSX::NSColor.orangeColor else @color || OSX::NSColor.blueColor end end end # # If this file is the main file, then perform the followjng commands. # (This construct is often useful for adding simple unit tests to # library code.) # if __FILE__ == $0 # # First, to establish a connection to the window server, # we must initialize the application # $stderr.print "just wait ..." ; $stderr.flush application = OSX::NSApplication.sharedApplication total_sec = 60 * 5 if not ARGV.empty? then total_sec = (60 * ARGV.shift.to_f).to_i FileUtils.rm_f(LT_START_TIME_PATH) end # Create the window window = OSX::NSWindow.alloc.initWithContentRect([0, 0, 450, 200], :styleMask, OSX::NSBorderlessWindowMask, :backing, OSX::NSBackingStoreBuffered, :defer, 0) # Allow the window to be partially transparent window.setOpaque(0) # Setup the window's root view view = HelloView.alloc.initWithFrame([0, 0, 450, 200]) view.total_sec = total_sec window.setContentView(view) # # Place the window near the top of the screen. # (Screen coordinates in Cocoa are always PostScript # coordinates, which start from the bottom of the screen # and increase as they go up, so we have to do some math # to place the window at 100 pixels from the top of the # screen. # screenFrame = OSX::NSScreen.mainScreen.frame windowOriginPoint = [40, screenFrame.origin.y + screenFrame.size.height - 100] window.setFrameOrigin( windowOriginPoint ) # Show the window window.makeKeyAndOrderFront(nil) window.setLevel(13) window.orderFrontRegardless() ## but this one does # And start the application event loop $stderr.print "\rtype `Ctrl-C' for quit !\n" trap('SIGINT') { $stderr.puts "bye." ; exit 0 } Thread.start { application.run } loop { sleep 0.2 view.setNeedsDisplay(true) window.orderFrontRegardless() } end