hotcocoa 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/History.txt +4 -0
  2. data/bin/hotcocoa +31 -0
  3. data/lib/hotcocoa/application_builder.rb +320 -0
  4. data/lib/hotcocoa/attributed_string.rb +143 -0
  5. data/lib/hotcocoa/behaviors.rb +7 -0
  6. data/lib/hotcocoa/data_sources/combo_box_data_source.rb +44 -0
  7. data/lib/hotcocoa/data_sources/table_data_source.rb +18 -0
  8. data/lib/hotcocoa/delegate_builder.rb +85 -0
  9. data/lib/hotcocoa/graphics/canvas.rb +836 -0
  10. data/lib/hotcocoa/graphics/color.rb +781 -0
  11. data/lib/hotcocoa/graphics/elements/particle.rb +75 -0
  12. data/lib/hotcocoa/graphics/elements/rope.rb +99 -0
  13. data/lib/hotcocoa/graphics/elements/sandpainter.rb +71 -0
  14. data/lib/hotcocoa/graphics/gradient.rb +63 -0
  15. data/lib/hotcocoa/graphics/image.rb +488 -0
  16. data/lib/hotcocoa/graphics/path.rb +325 -0
  17. data/lib/hotcocoa/graphics/pdf.rb +71 -0
  18. data/lib/hotcocoa/graphics.rb +161 -0
  19. data/lib/hotcocoa/kernel_ext.rb +14 -0
  20. data/lib/hotcocoa/kvo_accessors.rb +48 -0
  21. data/lib/hotcocoa/layout_view.rb +448 -0
  22. data/lib/hotcocoa/mapper.rb +227 -0
  23. data/lib/hotcocoa/mapping_methods.rb +40 -0
  24. data/lib/hotcocoa/mappings/alert.rb +25 -0
  25. data/lib/hotcocoa/mappings/application.rb +112 -0
  26. data/lib/hotcocoa/mappings/array_controller.rb +87 -0
  27. data/lib/hotcocoa/mappings/box.rb +39 -0
  28. data/lib/hotcocoa/mappings/button.rb +92 -0
  29. data/lib/hotcocoa/mappings/collection_view.rb +44 -0
  30. data/lib/hotcocoa/mappings/color.rb +28 -0
  31. data/lib/hotcocoa/mappings/column.rb +21 -0
  32. data/lib/hotcocoa/mappings/combo_box.rb +24 -0
  33. data/lib/hotcocoa/mappings/control.rb +33 -0
  34. data/lib/hotcocoa/mappings/font.rb +44 -0
  35. data/lib/hotcocoa/mappings/gradient.rb +15 -0
  36. data/lib/hotcocoa/mappings/image.rb +15 -0
  37. data/lib/hotcocoa/mappings/image_view.rb +43 -0
  38. data/lib/hotcocoa/mappings/label.rb +25 -0
  39. data/lib/hotcocoa/mappings/layout_view.rb +9 -0
  40. data/lib/hotcocoa/mappings/menu.rb +71 -0
  41. data/lib/hotcocoa/mappings/menu_item.rb +47 -0
  42. data/lib/hotcocoa/mappings/movie.rb +13 -0
  43. data/lib/hotcocoa/mappings/movie_view.rb +27 -0
  44. data/lib/hotcocoa/mappings/notification.rb +17 -0
  45. data/lib/hotcocoa/mappings/popup.rb +110 -0
  46. data/lib/hotcocoa/mappings/progress_indicator.rb +68 -0
  47. data/lib/hotcocoa/mappings/scroll_view.rb +29 -0
  48. data/lib/hotcocoa/mappings/search_field.rb +9 -0
  49. data/lib/hotcocoa/mappings/secure_text_field.rb +17 -0
  50. data/lib/hotcocoa/mappings/segmented_control.rb +97 -0
  51. data/lib/hotcocoa/mappings/slider.rb +25 -0
  52. data/lib/hotcocoa/mappings/sort_descriptor.rb +13 -0
  53. data/lib/hotcocoa/mappings/sound.rb +9 -0
  54. data/lib/hotcocoa/mappings/speech_synthesizer.rb +25 -0
  55. data/lib/hotcocoa/mappings/split_view.rb +21 -0
  56. data/lib/hotcocoa/mappings/status_bar.rb +7 -0
  57. data/lib/hotcocoa/mappings/status_item.rb +9 -0
  58. data/lib/hotcocoa/mappings/table_view.rb +110 -0
  59. data/lib/hotcocoa/mappings/text_field.rb +41 -0
  60. data/lib/hotcocoa/mappings/text_view.rb +13 -0
  61. data/lib/hotcocoa/mappings/timer.rb +25 -0
  62. data/lib/hotcocoa/mappings/toolbar.rb +97 -0
  63. data/lib/hotcocoa/mappings/toolbar_item.rb +36 -0
  64. data/lib/hotcocoa/mappings/view.rb +67 -0
  65. data/lib/hotcocoa/mappings/web_view.rb +22 -0
  66. data/lib/hotcocoa/mappings/window.rb +118 -0
  67. data/lib/hotcocoa/mappings/xml_parser.rb +41 -0
  68. data/lib/hotcocoa/mappings.rb +109 -0
  69. data/lib/hotcocoa/mvc.rb +175 -0
  70. data/lib/hotcocoa/notification_listener.rb +62 -0
  71. data/lib/hotcocoa/object_ext.rb +22 -0
  72. data/lib/hotcocoa/plist.rb +45 -0
  73. data/lib/hotcocoa/standard_rake_tasks.rb +17 -0
  74. data/lib/hotcocoa/template.rb +27 -0
  75. data/lib/hotcocoa/virtual_file_system.rb +172 -0
  76. data/lib/hotcocoa.rb +26 -0
  77. data/template/Rakefile +5 -0
  78. data/template/config/build.yml +8 -0
  79. data/template/lib/application.rb +45 -0
  80. data/template/lib/menu.rb +32 -0
  81. data/template/resources/HotCocoa.icns +0 -0
  82. data/test/test_helper.rb +3 -0
  83. data/test/test_hotcocoa.rb +11 -0
  84. metadata +137 -0
@@ -0,0 +1,109 @@
1
+ module HotCocoa
2
+ module Mappings
3
+
4
+ def self.reload
5
+ Dir.glob(File.join(File.dirname(__FILE__), "mappings", "*.rb")).each do |mapping|
6
+ require mapping
7
+ end
8
+ end
9
+
10
+ DefaultEmptyRect = [0,0,0,0]
11
+
12
+ module TargetActionConvenience
13
+ def on_action=(behavior)
14
+ if target && (
15
+ target.instance_variable_get("@action_behavior") ||
16
+ target.instance_variable_get("@double_action_behavior"))
17
+ object.instance_variable_set("@action_behavior", behavior)
18
+ object = target
19
+ else
20
+ object = Object.new
21
+ object.instance_variable_set("@action_behavior", behavior)
22
+ setTarget(object)
23
+ end
24
+ def object.perform_action(sender)
25
+ @action_behavior.call(sender)
26
+ end
27
+ setAction("perform_action:")
28
+ end
29
+
30
+ def on_action(&behavior)
31
+ self.on_action = behavior
32
+ self
33
+ end
34
+ end
35
+
36
+ # TODO: Needs docs for all possible invocations and examples!
37
+ def self.map(options, &block)
38
+ framework = options.delete(:framework)
39
+ mapped_name = options.keys.first
40
+ mapped_value = options.values.first
41
+ args = [mapped_name, mapped_value]
42
+
43
+ if mapped_value.kind_of?(Class)
44
+ add_mapping(*args, &block)
45
+ else
46
+ if framework.nil? || loaded_framework?(framework)
47
+ add_constant_mapping(*args, &block)
48
+ else
49
+ on_framework(framework) do
50
+ add_constant_mapping(*args, &block)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # Registers +mapped_name+ as a Mapper#builder_method for the given
57
+ # +mapped_value+. The +block+ is used as the Mapper#builder_method's body.
58
+ def self.add_mapping(mapped_name, mapped_value, &block)
59
+ m = Mapper.map_instances_of(mapped_value, mapped_name, &block)
60
+ mappings[m.builder_method] = m
61
+ end
62
+
63
+ # Registers +mapped_name+ as a Mapper#builder_method for the given
64
+ # +constant+ string which will be looked up. The +block+ is used as the
65
+ # Mapper#builder_method's body.
66
+ def self.add_constant_mapping(mapped_name, constant, &block)
67
+ add_mapping(mapped_name, Object.full_const_get(constant), &block)
68
+ end
69
+
70
+ # Returns the Hash of mappings.
71
+ def self.mappings
72
+ @mappings ||= {}
73
+ end
74
+
75
+ # Registers a callback for after the specified framework has been loaded.
76
+ def self.on_framework(name, &block)
77
+ (frameworks[name.to_s] ||= []) << block
78
+ end
79
+
80
+ # Returns the Hash of mapped frameworks.
81
+ def self.frameworks
82
+ @frameworks ||= {}
83
+ end
84
+
85
+ # Returns the Set of loaded frameworks.
86
+ def self.loaded_frameworks
87
+ @loaded_frameworks ||= Set.new
88
+ end
89
+
90
+ # Registers a given framework as being loaded.
91
+ def self.framework_loaded
92
+ frameworks.keys.each do |key|
93
+ if loaded_framework?(key)
94
+ frameworks[key].each do |mapper|
95
+ mapper.call
96
+ end
97
+ frameworks.delete(key)
98
+ end
99
+ end
100
+ end
101
+
102
+ # Returns whether or not the framework has been loaded yet.
103
+ def self.loaded_framework?(name)
104
+ NSBundle.allFrameworks.map {|bundle| bundle.bundlePath.split("/").last}.select {|framework| framework.split(".")[1] == 'framework'}.map {|framework| framework.split(".")[0]}.include?(name.to_s)
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,175 @@
1
+ require 'hotcocoa'
2
+
3
+ class HotCocoaApplication
4
+ attr_accessor :shared_application, :application_controller, :controllers
5
+
6
+ include HotCocoa
7
+
8
+ def self.instance=(instance)
9
+ @instance = instance
10
+ end
11
+
12
+ def self.instance
13
+ @instance
14
+ end
15
+
16
+ def initialize(application_file)
17
+ HotCocoaApplication.instance = self
18
+ @controllers = {}
19
+ load_controllers_and_views(directory_of(application_file))
20
+ @shared_application = application(ApplicationView.options[:application])
21
+ @shared_application.load_application_menu
22
+ @application_controller = controller(:application_controller)
23
+ shared_application.delegate_to(application_controller)
24
+ end
25
+
26
+ def start
27
+ @shared_application.run
28
+ end
29
+
30
+ def controller(controller_name)
31
+ controller_name_string = controller_name.to_s
32
+ controller_class = Object.const_get(controller_name_string !~ /_/ && controller_name_string =~ /[A-Z]+.*/ ? controller_name_string : controller_name_string.split('_').map{|e| e.capitalize}.join)
33
+ @controllers[controller_name] || create_controller_instance(controller_name, controller_class)
34
+ end
35
+
36
+ private
37
+
38
+ def create_controller_instance(controller_name, controller_class)
39
+ controller_instance = controller_class.new(self)
40
+ @controllers[controller_name] = controller_instance
41
+ controller_instance.application_window
42
+ controller_instance
43
+ end
44
+
45
+ def directory_of(application_file)
46
+ File.dirname(File.expand_path(application_file))
47
+ end
48
+
49
+ def load_controllers_and_views(directory)
50
+ Dir.glob(File.join(directory, 'controllers', '**', '*.rb')).each do |controller_file|
51
+ load(controller_file)
52
+ end
53
+ Dir.glob(File.join(directory, 'views', '**', '*.rb')).each do |view_file|
54
+ load(view_file)
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ class HotCocoaController
61
+
62
+ def self.view_instances
63
+ @view_instances ||= {}
64
+ end
65
+
66
+ attr_reader :application
67
+
68
+ def initialize(application)
69
+ @application = application
70
+ end
71
+
72
+ def application_window
73
+ @application.application_controller.application_window
74
+ end
75
+
76
+ end
77
+
78
+ class HotCocoaApplicationController < HotCocoaController
79
+
80
+ def initialize(application)
81
+ super(application)
82
+ end
83
+
84
+ def application_window
85
+ @application_window ||= ApplicationWindow.new(self).application_window
86
+ end
87
+
88
+ end
89
+
90
+ class HotCocoaWindow
91
+
92
+ attr_reader :application_controller, :application_window
93
+
94
+ def initialize(application_controller)
95
+ @application_controller = application_controller
96
+ render
97
+ end
98
+
99
+ def render
100
+ @application_window = HotCocoa.window(ApplicationView.options[:window])
101
+ @application_window.delegate_to(application_controller)
102
+ @application_window.view << application_controller.application_view
103
+ end
104
+
105
+ end
106
+
107
+ class HotCocoaView < HotCocoa::LayoutView
108
+
109
+ DefaultLayoutOptions = {:expand => [:width, :height]}
110
+
111
+ module ClassMethods
112
+ def controller(name=nil)
113
+ if name
114
+ @name = name
115
+ else
116
+ @name || :application_controller
117
+ end
118
+ end
119
+ def options(options=nil)
120
+ if options
121
+ @options = options
122
+ else
123
+ @options
124
+ end
125
+ end
126
+ end
127
+
128
+ def self.inherited(klass)
129
+ klass.extend(ClassMethods)
130
+ klass.send(:include, HotCocoa::Behaviors)
131
+ class_name = klass.name.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
132
+ HotCocoaController.class_eval %{
133
+ def #{class_name}
134
+ unless HotCocoaController.view_instances[:#{class_name}]
135
+ HotCocoaController.view_instances[:#{class_name}] = #{klass.name}.alloc.initWithFrame([0,0,0,0])
136
+ HotCocoaController.view_instances[:#{class_name}].setup_view
137
+ end
138
+ HotCocoaController.view_instances[:#{class_name}]
139
+ end
140
+ }, __FILE__, __LINE__
141
+ end
142
+
143
+ attr_reader :controller
144
+
145
+ def setup_view
146
+ unless @controller
147
+ @controller = class_controller
148
+ self.layout = layout_options
149
+ render
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ def class_controller
156
+ HotCocoaApplication.instance.controller(self.class.controller)
157
+ end
158
+
159
+ def layout_options
160
+ options = if self.class.options && self.class.options[:layout]
161
+ self.class.options[:layout]
162
+ else
163
+ DefaultLayoutOptions
164
+ end
165
+ end
166
+
167
+ end
168
+
169
+ class ApplicationWindow < HotCocoaWindow
170
+
171
+ end
172
+
173
+ class Application < HotCocoaApplication
174
+
175
+ end
@@ -0,0 +1,62 @@
1
+ module HotCocoa
2
+
3
+ class NotificationListener
4
+
5
+ DistributedBehaviors = {
6
+ :drop => NSNotificationSuspensionBehaviorDrop,
7
+ :coalesce => NSNotificationSuspensionBehaviorCoalesce,
8
+ :hold => NSNotificationSuspensionBehaviorHold,
9
+ :deliver_immediately => NSNotificationSuspensionBehaviorDeliverImmediately
10
+ }
11
+
12
+ attr_reader :callback, :name, :sender, :suspension_behavior
13
+
14
+ def self.registered_listeners
15
+ @registered_listeners ||= []
16
+ end
17
+
18
+ def initialize(options={}, &block)
19
+ @callback = block
20
+ @distributed = (options[:distributed] == true)
21
+ @suspension_behavior = DistributedBehaviors[options[:when_suspended] || :coalesce]
22
+ @name = options[:named]
23
+ @sender = options[:sent_by]
24
+ NotificationListener.registered_listeners << self
25
+ observe
26
+ end
27
+
28
+ def distributed?
29
+ @distributed
30
+ end
31
+
32
+ def receive(notification)
33
+ callback.call(notification)
34
+ end
35
+
36
+ def stop_notifications(options={})
37
+ if options.has_key?(:named) || options.has_key?(:sent_by)
38
+ notification_center.removeObserver(self, name:options[:named], object:options[:sender])
39
+ else
40
+ notification_center.removeObserver(self)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def observe
47
+ if distributed?
48
+ notification_center.addObserver self, selector:'receive:', name:name, object:sender, suspensionBehavior:suspension_behavior
49
+ else
50
+ notification_center.addObserver self, selector:'receive:', name:name, object:sender
51
+ end
52
+ end
53
+
54
+ def notification_center
55
+ @notification_center ||= (distributed? ? NSDistributedNotificationCenter.defaultCenter : NSNotificationCenter.defaultCenter)
56
+ end
57
+ end
58
+
59
+ def on_notification(options={}, &block)
60
+ NotificationListener.new(options, &block)
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ # Object.full_const_get was taken from the ‘extlib’ project:
2
+ # http://github.com/sam/extlib which is released under a MIT License and
3
+ # copyrighted by Sam Smoot (2008).
4
+
5
+ class Object
6
+
7
+ # @param name<String> The name of the constant to get, e.g. "Merb::Router".
8
+ #
9
+ # @return <Object> The constant corresponding to the name.
10
+ def full_const_get(name)
11
+ list = name.split("::")
12
+ list.shift if list.first.empty?
13
+ obj = self
14
+ list.each do |x|
15
+ # This is required because const_get tries to look for constants in the
16
+ # ancestor chain, but we only want constants that are HERE
17
+ obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
18
+ end
19
+ obj
20
+ end
21
+
22
+ end
@@ -0,0 +1,45 @@
1
+ module HotCocoa
2
+ def read_plist(data, mutability=:all)
3
+ mutability = case mutability
4
+ when :none
5
+ NSPropertyListImmutable
6
+ when :containers_only
7
+ NSPropertyListMutableContainers
8
+ when :all
9
+ NSPropertyListMutableContainersAndLeaves
10
+ else
11
+ raise ArgumentError, "invalid mutability `#{mutability}'"
12
+ end
13
+ if data.is_a?(String)
14
+ data = data.dataUsingEncoding(NSUTF8StringEncoding)
15
+ if data.nil?
16
+ raise ArgumentError, "cannot convert string `#{data}' to data"
17
+ end
18
+ end
19
+ # TODO retrieve error description and raise it if there is an error.
20
+ NSPropertyListSerialization.propertyListFromData(data,
21
+ mutabilityOption:mutability,
22
+ format:nil,
23
+ errorDescription:nil)
24
+ end
25
+ end
26
+
27
+ class Object
28
+ def to_plist(format=:xml)
29
+ format = case format
30
+ when :xml
31
+ NSPropertyListXMLFormat_v1_0
32
+ when :binary
33
+ NSPropertyListBinaryFormat_v1_0
34
+ when :open_step
35
+ NSPropertyListOpenStepFormat
36
+ else
37
+ raise ArgumentError, "invalid format `#{format}'"
38
+ end
39
+ # TODO retrieve error description and raise it if there is an error.
40
+ data = NSPropertyListSerialization.dataFromPropertyList(self,
41
+ format:format,
42
+ errorDescription:nil)
43
+ NSMutableString.alloc.initWithData(data, encoding:NSUTF8StringEncoding)
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ AppConfig = HotCocoa::ApplicationBuilder::Configuration.new("config/build.yml")
2
+
3
+ task :deploy => [:clean] do
4
+ HotCocoa::ApplicationBuilder.build(AppConfig, :deploy => true)
5
+ end
6
+
7
+ task :build do
8
+ HotCocoa::ApplicationBuilder.build(AppConfig)
9
+ end
10
+
11
+ task :run => [:build] do
12
+ `"./#{AppConfig.name}.app/Contents/MacOS/#{AppConfig.name.gsub(/ /, '')}"`
13
+ end
14
+
15
+ task :clean do
16
+ `/bin/rm -rf "#{AppConfig.name}.app"`
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'fileutils'
2
+ require 'rbconfig'
3
+
4
+ module HotCocoa
5
+ class Template
6
+
7
+ def self.source_directory
8
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
9
+ end
10
+
11
+ def self.copy_to(directory, app_name)
12
+ FileUtils.mkdir_p(directory)
13
+ Dir.glob(File.join(source_directory, "template", "**/*")).each do |file|
14
+ short_name = file[(source_directory.length+10)..-1]
15
+ if File.directory?(file)
16
+ FileUtils.mkdir_p File.join(directory, short_name)
17
+ else
18
+ File.open(File.join(directory, short_name), "w") do |out|
19
+ input = File.read(file)
20
+ input.gsub!(/__APPLICATION_NAME__/, app_name)
21
+ out.write input
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,172 @@
1
+ class VirtualFileSystem
2
+
3
+ def self.code_to_load(main_file, password = "\320\302\354\024\215\360P\235\2244\261\214\276:'\274%\270<\350t\212\003\340\t'\004\345\334\256\315\277")
4
+ <<-VFS
5
+ module DatabaseRuntime
6
+
7
+ class VirtualFilesystem
8
+
9
+ attr_reader :password, :encryption_method
10
+
11
+ def initialize(password, encryption_method="aes256")
12
+ @password = password
13
+ @encryption_method = encryption_method
14
+ end
15
+
16
+ def open_database(main_database)
17
+ @main_database = main_database
18
+ begin
19
+ @db = Marshal.load(File.open(main_database, "rb") {|f| f.read})
20
+ rescue
21
+ puts $!
22
+ puts $!.backtrace.join("\\n")
23
+ end
24
+ end
25
+
26
+ def read_file_and_key(filename)
27
+ data, key = read_file_using_path(filename)
28
+ if data.nil? && filename[0,1] != "/"
29
+ $:.each do |loadpath|
30
+ data, key = read_file_using_path(filename, expand_path(loadpath))
31
+ break if data
32
+ end
33
+ end
34
+ [data, key]
35
+ end
36
+
37
+ def read_file_using_path(filename, pathname="/")
38
+ path = expand_path(File.join(pathname, filename))
39
+ rb_ext = false
40
+ if has_key?(path)
41
+ key = filename
42
+ elsif self.has_key?(path+".rb")
43
+ key = filename+".rb"
44
+ rb_ext = true
45
+ end
46
+ if key
47
+ result = rb_ext ? self[path+".rb"] : self[path]
48
+ if result
49
+ result.gsub!(/__FILE__/, "'\#{path + (rb_ext ? ".rb" : '')}'")
50
+ return result, key
51
+ end
52
+ end
53
+ nil
54
+ end
55
+
56
+ def has_key?(key)
57
+ @db.has_key?(key)
58
+ end
59
+
60
+ def delete(key)
61
+ end
62
+
63
+ def [](key)
64
+ read(@db, key)
65
+ end
66
+
67
+ def close
68
+ end
69
+
70
+ def keys
71
+ @db.keys
72
+ end
73
+
74
+ def []=(key, value)
75
+ end
76
+
77
+ def normalize(filename)
78
+ f = filename.split(File::Separator)
79
+ f.delete(".")
80
+ while f.include?("..")
81
+ f[f.index("..")-1,2] = []
82
+ end
83
+ f.join(File::Separator)
84
+ end
85
+
86
+ private
87
+
88
+ def expand_path(filename, dirstring=nil)
89
+ filename = File.join(dirstring, filename) if dirstring
90
+ f = filename.split(File::Separator)
91
+ f.delete(".")
92
+ f.delete("")
93
+ while f.include?("..")
94
+ f[f.index("..")-1,2] = []
95
+ end
96
+ "/"+f.join(File::Separator)
97
+ end
98
+
99
+
100
+ def read(db, key)
101
+ if db.has_key?(key)
102
+ #decrypt = OpenSSL::Cipher::Cipher.new(encryption_method)
103
+ #decrypt.decrypt
104
+ #decrypt.key = password
105
+ #data = decrypt.update(db[key])
106
+ #data << decrypt.final
107
+ #::Zlib::Inflate.inflate(data)
108
+ db[key]
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+
118
+ $ROOT_BINDING = binding
119
+
120
+ module Kernel
121
+
122
+ def virtual_filesystems(options)
123
+ vfs = DatabaseRuntime::VirtualFilesystem.new(options["password"])
124
+ vfs.open_database(options["database"])
125
+ Kernel.const_set("VIRTUAL_FILESYSTEM", vfs)
126
+ vfs
127
+ end
128
+
129
+ alias_method :original_require, :require
130
+
131
+ def require(path)
132
+ path = VIRTUAL_FILESYSTEM.normalize(path)
133
+ path_loaded = $".include?(path) || $".include?(path+".rb") || $".include?(path+".so")
134
+ unless path_loaded
135
+ data, key = VIRTUAL_FILESYSTEM.read_file_and_key(path)
136
+ if data
137
+ $" << key
138
+ eval(data, $ROOT_BINDING, key, 0)
139
+ return true
140
+ else
141
+ original_require(path)
142
+ end
143
+ else
144
+ return false
145
+ end
146
+ end
147
+
148
+ alias_method :original_load, :load
149
+
150
+ def load(path)
151
+ path = VIRTUAL_FILESYSTEM.normalize(path)
152
+ data, key = VIRTUAL_FILESYSTEM.read_file_and_key(path)
153
+ if data
154
+ eval(data, $ROOT_BINDING, key, 0)
155
+ return true
156
+ else
157
+ begin
158
+ original_load(path)
159
+ rescue LoadError => e
160
+ raise e
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ virtual_filesystems("database"=>File.join(NSBundle.mainBundle.resourcePath.fileSystemRepresentation, 'vfs.db'), "password"=>#{password.inspect})
168
+ $:.unshift "/lib"
169
+ load '#{main_file}'
170
+ VFS
171
+ end
172
+ end
data/lib/hotcocoa.rb ADDED
@@ -0,0 +1,26 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ framework 'Cocoa'
5
+
6
+ module Hotcocoa
7
+ VERSION = '0.0.1'
8
+ Views = {}
9
+ end
10
+
11
+ require 'hotcocoa/object_ext'
12
+ require 'hotcocoa/kernel_ext'
13
+ require 'hotcocoa/mappings'
14
+ require 'hotcocoa/behaviors'
15
+ require 'hotcocoa/mapping_methods'
16
+ require 'hotcocoa/mapper'
17
+ require 'hotcocoa/layout_view'
18
+ require 'hotcocoa/delegate_builder'
19
+ require 'hotcocoa/notification_listener'
20
+ require 'hotcocoa/data_sources/table_data_source'
21
+ require 'hotcocoa/data_sources/combo_box_data_source'
22
+ require 'hotcocoa/plist'
23
+ require 'hotcocoa/kvo_accessors'
24
+ require 'hotcocoa/attributed_string'
25
+
26
+ HotCocoa::Mappings.reload
data/template/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'hotcocoa/application_builder'
3
+ require 'hotcocoa/standard_rake_tasks'
4
+
5
+ task :default => [:run]
@@ -0,0 +1,8 @@
1
+ name: __APPLICATION_NAME__
2
+ load: lib/application.rb
3
+ version: "1.0"
4
+ icon: resources/HotCocoa.icns
5
+ resources:
6
+ - resources/**/*.*
7
+ sources:
8
+ - lib/**/*.rb