Skip to content

Commit

Permalink
More progress on Mac support.
Browse files Browse the repository at this point in the history
  • Loading branch information
jacius committed Aug 6, 2010
1 parent a31a161 commit 3b299d9
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 93 deletions.
211 changes: 122 additions & 89 deletions lib/ruby-sdl-ffi/sdl/mac.rb
Expand Up @@ -42,96 +42,89 @@

module SDL::Mac

def self.inspect_menu( menu, indent="" )
puts "%s-%s (%s \"%s\", %d items)"%[indent, menu, menu.classname,
menu.title, menu.length]
menu.each do |ob|
if ob.hasSubmenu?
inspect_menu( ob.submenu, indent+" " )
else
puts "%s -%s (%s \"%s\")"%[indent, ob, ob.classname, ob.title]
end
class << self

def make_menus( app_name )
ptr = FFI.find_type(:pointer)

nsapp = Cocoa.NSApp
menubar = Cocoa::NSMenu.new.initWithTitle("AMainMenu")
nsapp.msg( "setMainMenu:", ptr, menubar )

remove_bold_menu( nsapp, menubar )
make_app_menu( menubar, app_name )
make_window_menu( nsapp, menubar )

nil
end

private

# Hack to remove the bold "ruby" menu (aka the "Apple" menu).
# It's a ghost menu, it haunts us but can't be modified.
def remove_bold_menu( nsapp, menubar )
item = Cocoa::NSMenuItem.new.initWithTitle("AppleMenu")
menu = Cocoa::NSMenu.new.initWithTitle("AppleMenu")
item.submenu = menu

nsapp.msg("setAppleMenu:", FFI.find_type(:pointer), menu)
menubar.addItem(item)
menubar.removeItem(item)

item.release
menu.release
end


# Create the main menu with the app's name (Hide, Quit, etc.)
def make_app_menu( menubar, app_name )
item = Cocoa::NSMenuItem.new.initWithTitle( app_name )
menu = Cocoa::NSMenu.new.initWithTitle( app_name )
item.submenu = menu
menubar.addItem(item)

menu.addItemWithTitle("Hide #{app_name}", "hide:")
menu.addItemWithTitle("Hide Others", "hideOtherApplications:")
menu.addItemWithTitle("Show All", "unhideAllApplications:")

# Can't get the Quit menu item to work right yet.
#menu.addItem( Cocoa::NSMenuItem.separatorItem )
#menu.addItemWithTitle("Quit #{app_name}", "terminate:")

item.release
menu.release
end


# Create the "Window" menu (Minimize, etc.)
def make_window_menu( nsapp, menubar )
ptr = FFI.find_type(:pointer)

item = Cocoa::NSMenuItem.new.initWithTitle("Window")
menu = Cocoa::NSMenu.new.initWithTitle("Window")
item.submenu = menu
menubar.addItem(item)
nsapp.msg("setWindowsMenu:", ptr, menu)

menu.addItemWithTitle("Minimize", "performMiniaturize:")

item.release
menu.release
end
end


def self.make_menus( new_title )
ptr = FFI.find_type(:pointer)

nsapp = Cocoa.NSApp

menubar = Cocoa::NSMenu.new.initWithTitle("AMainMenu")
nsapp.msg( "setMainMenu:", ptr, menubar )


# "Apple" menu - actually the "ruby" menu, supposedly.
appledummy = ObjC::NSMenuItem.new.initWithTitle("Apple")
applemenu = Cocoa::NSMenu.new.initWithTitle("Apple")
appledummy.submenu = applemenu
menubar.addItem(appledummy)
nsapp.msg( "setAppleMenu:", ptr, applemenu )

appledummy2 = ObjC::NSMenuItem.new.initWithTitle("Apple Item")
applemenu.addItem( appledummy2 )


# A new menu with the app's name
appdummy = ObjC::NSMenuItem.new.initWithTitle(new_title)
appmenu = Cocoa::NSMenu.new.initWithTitle( new_title )
appdummy.submenu = appmenu
menubar.msg( "insertItem:atIndex:", ptr, appdummy, FFI.find_type(:int), 0 )
appdummy.release

appdummy2 = ObjC::NSMenuItem.new.initWithTitle("App Item")
appmenu.addItem( appdummy2 )


# Window menu
windowdummy = ObjC::NSMenuItem.new.initWithTitle("Window")
windowmenu = Cocoa::NSMenu.new.initWithTitle("Window")
windowdummy.submenu = windowmenu
menubar.addItem( windowdummy )
nsapp.msg( "setWindowsMenu:", ptr, windowmenu )
windowdummy.release

windowdummy2 = ObjC::NSMenuItem.new.initWithTitle("Window Item")
windowmenu.addItem( windowdummy2 )

inspect_menu( menubar )

nil
end


# Sets the application menu title on Mac OS X, i.e. the bold word
# in the application menu at the top of the screen.
#
def self.set_app_title( new_title )
ptr = FFI.find_type(:pointer)
long = FFI.find_type(:long)

nsapp = Cocoa.NSApp

menubar = nsapp.msg( "mainMenu" )
inspect_menu( menubar )

appdummy = menubar[0]
appmenu = appdummy.submenu
appmenu.title = new_title
inspect_menu( appmenu )
menubar.msg( "itemChanged:", ptr, appdummy )

# windowdummy = menubar.[1]
# windowmenu = windowdummy.submenu
# windowmenu.title = new_title
# inspect_menu( windowmenu )

menubar.msg( "update" )
def inspect_menu( menu, indent="" )
puts "%s-%s (%s \"%s\", %d items)"%[indent, menu, menu.classname,
menu.title, menu.length]
menu.each do |ob|
if ob.hasSubmenu?
inspect_menu( ob.submenu, indent+" " )
else
puts "%s -%s (%s \"%s\")"%[indent, ob, ob.classname, ob.title]
end
end
end

# menubar.msg( "removeItemAtIndex:", long, 0 )
# inspect_menu( menubar )

nil
end


Expand Down Expand Up @@ -171,7 +164,7 @@ def self.load_nib( nibpath = :default )
count = toplevel.msg_int("count")
count.times do |i|
ob = toplevel.msg("objectAtIndex:", FFI.find_type(:long), i)
case ob.classname
case ob.nsclassname
when "NSMenu"; menubar = Cocoa::NSMenu(ob.pointer)
when "NSApplication"; app = ob
end
Expand All @@ -196,16 +189,23 @@ module ObjC


class NSObject < NiceFFI::OpaqueStruct
# define msg, msg_ptr, msg_str, msg_int, msg_bool
def self.nsclassname; name.split("::")[-1]; end

# define msg, msg_ptr, msg_str, msg_int, msg_bool (and class methods)
["", "_ptr", "_str", "_int", "_bool"].each do |suffix|
module_eval("
def msg#{suffix}( message, *args )
ObjC.msgSend#{suffix}( @pointer, message, *args )
end
def self.msg#{suffix}( message, *args )
ObjC.msgSend#{suffix}( ObjC.NSClass(self.nsclassname),
message, *args )
end")
end

def inspect; msg_str("description").to_s; end
def classname; ObjC.object_getClassName(@pointer); end
def nsclassname; ObjC.object_getClassName(@pointer); end
def release; msg("release"); end
end

Expand Down Expand Up @@ -337,6 +337,26 @@ def addItem( item )
self
end

def addItemWithTitle( title, action=nil, keyEquivalent="" )
ptr = FFI.find_type(:pointer)
action = ObjC.sel(action) if action.is_a? String
item = msg_ptr( "addItemWithTitle:action:keyEquivalent:",
ptr, ObjC::NSString(title),
ptr, action,
ptr, ObjC::NSString(keyEquivalent))
NSMenuItem.new(item)
end

def removeItem( item )
msg("removeItem:", FFI.find_type(:pointer), item)
self
end

def removeItemAtIndex( index )
msg("removeItemAtIndex:", FFI.find_type(:long), index)
self
end

def length
msg_int( "numberOfItems" )
end
Expand All @@ -356,6 +376,10 @@ def self.NSMenu( *args )


class NSMenuItem < ObjC::NSObject
def self.separatorItem
new( msg_ptr("separatorItem") )
end

def initialize( *args )
if args.empty?
super( ObjC::NSClass("NSMenuItem").msg_ptr("alloc") )
Expand All @@ -366,6 +390,7 @@ def initialize( *args )

def initWithTitle( title, action=nil, keyEquivalent="" )
ptr = FFI.find_type(:pointer)
action = ObjC.sel(action) if action.is_a? String
msg( "initWithTitle:action:keyEquivalent:",
ptr, ObjC::NSString(title),
ptr, action,
Expand Down Expand Up @@ -407,6 +432,14 @@ def self.NSMenuItem( *args )
NSNibTopLevelObjects =
ObjC::NSString( ObjC::NSString(self.vNSNibTopLevelObjects).to_s )

NSAlphaShiftKeyMask = 1 << 16
NSShiftKeyMask = 1 << 17
NSControlKeyMask = 1 << 18
NSAlternateKeyMask = 1 << 19
NSCommandKeyMask = 1 << 20
NSNumericPadKeyMask = 1 << 21
NSHelpKeyMask = 1 << 22
NSFunctionKeyMask = 1 << 23
end


Expand Down
8 changes: 4 additions & 4 deletions lib/ruby-sdl-ffi/sdl/video.rb
Expand Up @@ -277,10 +277,10 @@ def self.release( pointer )
def self.SetVideoMode( *args )
result = __SetVideoMode(*args)
if defined? SDL::Mac
SDL::Mac::HIServices.make_current_front()
SDL::Mac.load_nib
# SDL::Mac.make_menus("My App")
# SDL::Mac.set_app_title("My App")
#SDL::Mac::ObjC.msgSend(SDL::Mac::Cocoa.NSApp, "finishLaunching")
SDL::Mac::HIServices.make_current_front
# SDL::Mac.load_nib
SDL::Mac.make_menus("Rubygame Demo")
end
return result
end
Expand Down

0 comments on commit 3b299d9

Please sign in to comment.